var vue = new Vue({
  el: "#page_container",
  data: function () {
    return {
      index: {
        name: "index",
        label: "主 页 ",
        queryForm: {
          queryString: "",
          likeChecked: false,
          loading: false,
          classType: [1, 3],
        },
        queryExpandRowKeys: [],
        queryResult: [],
        queryResultSortable: true,
        contextData: NaN,
        showAllContextData: false,
        openSourceURI: "https://gitee.com/mutongtech/ClassView",
      },
      enums: {
        //元数据类型
        classTypeOptions: [
          { value: 0, name: "基本", isQuery: false, isFilter: true },
          { value: 1, name: "实体", isQuery: true, isFilter: true },
          { value: 2, name: "属性", isQuery: true, isFilter: true },
          { value: 3, name: "枚举", isQuery: true, isFilter: true },
          { value: 4, name: "集合", isQuery: false, isFilter: true },
          { value: 7, name: "BPSV", isQuery: true, isFilter: false },
        ],
        //事务类型
        transactionTypeOptions: [
          { value: 0, name: "Required" },
          { value: 1, name: "RequiresNew" },
          { value: 2, name: "Supported" },
          { value: 3, name: "NotSupported" },
        ],
        //关联种类
        enumAssociationKindOptions: [
          { value: 0, code: "ASSOCIATION", name: "关联" },
          { value: 1, code: "COMPOSITION", name: "组合" },
        ],
        //关联种类
        queryOperatorOptions: [
          { value: 0, code: "%like", name: "左包含" },
          { value: 1, code: "like", name: "包含" },
          { value: 2, code: "like%", name: "右包含" },
          { value: 3, code: "equal", name: "等于" },
        ],
        //关联种类
        monacoEditorThemeOptions: [
          { value: 0, code: "vs", name: "vs" },
          { value: 1, code: "vs-dark", name: "vs-dark" },
          { value: 2, code: "hc-black", name: "hc-black" },
        ],
        //值集定义-类型
        ValueSetDefValidateTypeEnum: [
          { value: 1, code: "Entity", name: "实体" },
          { value: 2, code: "None", name: "无档案" },
          { value: 3, code: "ValueSet", name: "自定义" },
          { value: 4, code: "EnumType", name: "枚举" },
        ],
        //值集定义-段值类型
        ValueSetDefValueTypeEnum: [
          { value: 1, code: "VtInteger", name: "整数" },
          { value: 2, code: "VtString", name: "字符串" },
          { value: 3, code: "VtDate", name: "日期" },
          { value: 4, code: "VtNumber", name: "数字" },
          { value: 5, code: "VtBool", name: "布尔" },
          { value: 6, code: "VtDateTime", name: "日期时间" },
        ],
      },
      constObj: {
        descFlexSegmentsFullName:
          "UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegments",
      },
      currentTabIndex: "index",
      monacoEditorTheme: 0,
      tabs: [],
      metedatas: [],
      oqlExpressions: [],
      formulaExpressions: [],
      popover: {
        oqlExpressionActiveAttribute: NaN,
        oqlExpressionActiveReference: NaN,
        oqlExpressionShow: false,
        formulaExpressionActiveAttribute: NaN,
        formulaExpressionActiveReference: NaN,
        formulaExpressionShow: false,
      },
      isSetupCustomProxy: false,
    };
  },
  beforeCreate: function () {
    if (window && window.parent && window.parent.TabPanelManager) {
      let _parentWin = window.parent;
      let url = window.location.href;
      setTimeout(function () {
        _parentWin.TabPanelManager.killThis();
      }, 100);
      _parentWin.window.open(url, "_blank");
    }
  },
  created: function () {
    this.oqlExpressions = oqlExpressions;
    this.formulaExpressions = formulaExpressions;
    document.addEventListener("keydown", this.handleKeyEvent);
  },
  mounted: function () {
    require.config({
      paths: { vs: "../../classView/js/monaco-editor-0.46.0/min/vs" },
      "vs/nls": { availableLanguages: { "*": "zh-cn" } },
    });
    //获取当前上下文
    this.getCurrentContext();
    //获取是否启用自定义代理
    //this.getIsSetupCustomProxy();
    //初始化WordCloud
    this.initChartWordCloud();
  },
  methods: {
    api() {
      let $this = this;
      return {
        //查询元数据
        queryMetedata(parameter, resolve) {
          $.post("../classView/QueryMetedata", parameter, resolve);
        },
        //获取Metedata
        getMetedata(keyID, parentFullName, resolve) {
          let url =
            "../classView/GetMetedata?keyID=" +
            encodeURIComponent(keyID) +
            (parentFullName && parentFullName.length > 0
              ? "&parentFullName=" + encodeURIComponent(parentFullName)
              : "");
          $.get(url, resolve);
        },
        //获取当前上下文
        getCurrentContext(resolve) {
          $.post("../classView/GetCurrentContext", resolve);
        },
        //获取代理对象
        getProxyData(parameter, resolve) {
          $.post("../classView/GetProxyData", parameter, resolve);
        },
        //累计重载代理对象
        totalGetProxyData(parameter, resolve) {
          $.post("../classView/TotalGetProxyData", parameter, resolve);
        },
        //执行代理请求
        proxyDo(parameter, resolve) {
          $.post("../classView/ProxyDo", parameter, resolve);
        },
        //Oql转为Sql
        convertOqlToSql(oql, resolve) {
          $.post("../classView/ConvertOqlToSql", { oql: oql }, resolve);
        },
        //执行Oql
        runOQL(oql, pageParamter, resolve) {
          $.post(
            "../classView/RunOQL",
            { oql: oql, pageParamter: JSON.stringify(pageParamter) },
            resolve
          );
        },
        //开启事务调试
        setupTransactionDebug(resolve) {
          $.get("../classView/SetupTransactionDebug", {}, resolve);
        },
        //开启拦截调试
        setupProxyDoDebug(resolve) {
          $.get("../classView/SetupProxyDoDebug", {}, resolve);
        },
        //查询参照
        queryRef(parameter, resolve) {
          $.post("../classView/QueryRef", parameter, resolve);
        },
        //查询参照
        queryForm(parameter, resolve) {
          $.post("../classView/QueryForm", parameter, resolve);
        },
        //同步组合名称
        syncFieldCombineName(parameter, resolve) {
          $.post("../classView/SyncFieldCombineName", parameter, resolve);
        },
        //刷新全部枚举
        refreshAllEnum(resolve) {
          $.post("../classView/RefreshAllEnum", {}, resolve);
        },
        //刷新单个枚举
        refreshSingleEnum(parameter, resolve) {
          $.post("../classView/RefreshSingleEnum", parameter, resolve);
        },
        //是否启用自定义代理
        isSetupCustomProxy(resolve) {
          $.get("../classView/IsSetupCustomProxy", {}, resolve);
        },
      };
    },
    //#region 左侧通用按钮
    //回主页
    goHome() {
      this.currentTabIndex = this.index.name;
    },
    //回到上一页
    goBack(tab) {
      if (!tab) return;
      if (tab.preTabIndex) {
        let preTab = this.tabs.find((item) => {
          return item.name === tab.preTabIndex;
        });
        if (preTab) {
          this.currentTabIndex = tab.preTabIndex;
          return;
        }
      }
      this.currentTabIndex = this.index.name;
    },
    //刷新
    onRefresh(tab) {
      let $this = this;
      if (!tab.metedata) return;
      let classType = tab.metedata.ClassType;
      let keyID = tab.name;
      this.addMetedataTab(classType, keyID, true);
    },
    //#endregion
    //#region monaco.editor
    //获取编辑器配置
    getEditorConfig(language, value) {
      return {
        language: language,
        value: value,
        contextmenu: true,
        acceptSuggestionOnCommitCharacter: true,
        acceptSuggestionOnEnter: "on",
        accessibilityPageSize: 10,
        accessibilitySupport: "on",
        autoClosingBrackets: "always",
        autoClosingDelete: "always",
        autoClosingOvertype: "always",
        autoClosingQuotes: "always",
        autoIndent: "None",
        automaticLayout: true,
        codeLens: false,
        codeLensFontFamily: "",
        codeLensFontSize: 12,
        colorDecorators: false,
        comments: {
          ignoreEmptyLines: true,
          insertSpace: true,
        },
        columnSelection: false,
        autoSurround: "never",
        copyWithSyntaxHighlighting: true,
        cursorBlinking: "Solid",
        cursorSmoothCaretAnimation: true,
        cursorStyle: "UnderlineThin",
        cursorSurroundingLines: 0,
        cursorSurroundingLinesStyle: "all",
        cursorWidth: 2,
        minimap: {
          enabled: false,
        },
        folding: true,
        links: true,
        overviewRulerBorder: false,
        renderLineHighlight: "gutter",
        roundedSelection: false,
        scrollBeyondLastLine: false,
        readOnly: false,
        theme: "vs",
        fontSize: "12px",
        lineNumbers: "on",
      };
    },
    //格式化
    formatEditorValue(editor) {
      if (!editor) return;
      let language = editor._configuration._rawOptions.language;
      if (language === "json") {
        editor.trigger("anyString", "editor.action.formatDocument");
        editor.setValue(editor.getValue());
      }
      if (language === "sql") {
        require(["sqlFormatter"], function (sqlFormatter) {
          if (!sqlFormatter) return;
          let sql = editor.getValue();
          let config = {
            language: "tsql",
            expressionWidth: 100,
            keywordCase: editor.isOQL ? "lower" : "upper",
            functionCase: editor.isOQL ? "preserve" : "upper",
          };
          editor.setValue(sqlFormatter.format(sql, config));
        });
      }
    },
    //全部展开
    editorExpandAll(editor) {
      if (!editor) return;
      editor.trigger("unfold", "editor.unfoldAll");
    },
    //全部收缩
    editorCollapseAll(editor) {
      if (!editor) return;
      editor.trigger("fold", "editor.foldAll");
    },
    //当编辑器样式变化
    onMonacoEditorThemeChange() {
      if (typeof monaco === "undefined") return;
      let themeOption = this.enums.monacoEditorThemeOptions.find((option) => {
        return option.value == this.monacoEditorTheme;
      });
      if (themeOption) monaco.editor.setTheme(themeOption.code);
    },
    //#endregion
    //#region 元数据
    //获取Metedata
    getMetedata(keyID, parentFullName, resolve) {
      let metedatas = this.metedatas;
      let metedata = metedatas.find(
        (item) =>
          item.Key &&
          item.Key.ID ==
            keyID +
              (parentFullName && parentFullName.length > 0
                ? "_" + parentFullName
                : "")
      );
      if (metedata && resolve) {
        resolve(metedata);
        return;
      }
      let $this = this;
      this.api().getMetedata(keyID, parentFullName, function (res) {
        //console.log('res', res)
        if (res.code === 0) {
          //console.log('metedata name:', res.data.Name + '/' + res.data.DisplayName)
          //console.log('metedata', JSON.stringify(res.data))
          metedata = res.data;
          if (parentFullName && parentFullName.length > 0)
            metedata.Key.ID = metedata.Key.ID + "_" + parentFullName;
          $this.metedatas.push(metedata);
          if (resolve) resolve(metedata);
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //获取克隆后的Metedata
    getCloneMetedata(keyID, parentFullName, resolve) {
      this.getMetedata(keyID, parentFullName, function (metedata) {
        let cloneMetedata = $.extend(true, {}, metedata);
        if (resolve) resolve(cloneMetedata);
      });
    },
    //补齐Entity元数据
    patchEntityMetedata(metedata, parentAttribute, parentAssociation) {
      metedata.ID = Math.uuid();
      //补齐Entity元数据属性
      this.patchEntityMetedataAttributes(metedata, parentAttribute);
      //补齐Entity元数据关联
      this.patchEntityMetedataAssociations(metedata, parentAssociation);
    },
    //补齐Entity元数据属性
    patchEntityMetedataAttributes(metedata, parentAttribute) {
      let $this = this;
      if (parentAttribute) {
        metedata.tab = parentAttribute.metedata.tab;
        parentAttribute.childrenAttributes = metedata.Attributes;
      }
      metedata.Attributes.forEach((attribute, index) => {
        attribute.attributeID = Math.uuid();
        attribute.metedata = metedata;
        if (parentAttribute) {
          attribute.parentAttributeID = parentAttribute.attributeID;
        }
        attribute.parentAttribute = parentAttribute;
        attribute.hasChildren =
          attribute.DataTypeFlag == 1 ||
          attribute.DataTypeFlag === 2 ||
          attribute.DataTypeFlag === 4;
        //表达式
        if (metedata.ClassType === 2 && parentAttribute) {
          //属性
          attribute.expression =
            parentAttribute.metedata.Name +
            "." +
            parentAttribute.Name.concat(".", attribute.Key.Name);
          attribute.expressionDisplayName =
            parentAttribute.metedata.DisplayName +
            "." +
            parentAttribute.DisplayName.concat(".", attribute.DisplayName);
        } else {
          attribute.expression = metedata.Key.Name.concat(
            ".",
            attribute.Key.Name
          );
          attribute.expressionDisplayName = metedata.DisplayName.concat(
            ".",
            attribute.DisplayName
          );
        }

        if (parentAttribute) {
          //完整表达式
          attribute.fullExpression = parentAttribute.fullExpression.concat(
            ".",
            attribute.Key.Name
          );
          attribute.fullExpressionDisplayName =
            parentAttribute.fullExpressionDisplayName.concat(
              ".",
              attribute.DescFlexFieldDef && attribute.DescFlexFieldDef.Name
                ? attribute.DescFlexFieldDef.Name
                : attribute.DisplayName
            );
          attribute.level = parentAttribute.level + 1;
        } else {
          //完整表达式
          attribute.fullExpression = attribute.expression;
          attribute.fullExpressionDisplayName = attribute.expressionDisplayName;
          attribute.level = 1;
        }
        //关联(继承实体关联会不存在)
        if (attribute.DataTypeFlag === 1 || attribute.DataTypeFlag === 4) {
          let association = metedata.Associations.find((asso) => {
            return (
              asso.ParentMemberKey &&
              asso.ParentMemberKey.ID == attribute.Key.ID
            );
          });
          if (association) {
            attribute.DataTypeKey = association.ChildEntityKey;
            attribute.DataTypeKind = association.Kind;
            attribute.association = association;
          }
        }
        attribute.oqlExpressions = [];
        attribute.formulaExpressions = [];
      });
    },
    //补齐Entity元数据关联
    patchEntityMetedataAssociations(metedata, parentAssociation) {
      metedata.Associations.forEach((association, index) => {
        association.associationID = Math.uuid();
        association.metedata = metedata;
        association.parentAssociation = parentAssociation;
        if (parentAssociation) metedata.tab = parentAssociation.metedata.tab;
        association.children = [];
        //表达式
        association.expression = "".concat(
          association.ParentEntityKey.Name,
          ".",
          association.ParentMemberKey.Name
        );
        if (parentAssociation) {
          //完整表达式
          association.fullExpression = parentAssociation.fullExpression.concat(
            ".",
            association.ParentMemberKey.Name
          );
          association.level = parentAssociation.level + 1;
        } else {
          //完整表达式
          association.fullExpression = association.expression;
          association.level = 1;
        }
      });
    },
    //加载子实体关联
    loadChildrenAssociations(association, treeNode, resolve) {
      let keyID = association.ChildEntityKey.ID;
      let $this = this;
      this.getCloneMetedata(keyID, NaN, function (metedata) {
        //补齐Entity元数据关联
        $this.patchEntityMetedata(metedata, NaN, association);
        let associations = $this.filterAssociationsByKind(metedata, 1);
        association.children = associations;
        resolve(associations);
      });
    },
    //获取扩展字段
    getDescFlexSegmentsAttribute(metedata) {
      if (!metedata || !metedata.Attributes) return NaN;
      let attr = metedata.Attributes.find(
        (attribute) =>
          attribute.DataTypeKey &&
          attribute.DataTypeKey.FullName ==
            this.constObj.descFlexSegmentsFullName
      );
      return attr;
    },
    //复制所有的属性
    copyAllAttributes(metedata) {
      if (metedata && metedata.Attributes && metedata.Attributes.length > 0) {
        let content = "";
        metedata.Attributes.forEach((attribute, index) => {
          if (index > 0) {
            content += "\r";
          }
          content =
            content +
            attribute.Name +
            "\t" +
            attribute.DisplayName +
            (attribute.DefaultValue && attribute.DefaultValue !== ""
              ? "\t" + attribute.DefaultValue
              : "");
        });
        this.copyToClipboard(content);
      }
    },
    //#endregion
    //#region Tabs
    //Tabs编辑事件
    handleTabsEdit(targetName, action) {
      if (action === "remove") {
        if (targetName === this.index.name) return;
        let tabs = this.tabs;
        let activeName = this.currentTabIndex;
        if (activeName === targetName) {
          tabs.forEach((tab, index) => {
            if (tab.name === targetName) {
              activeName = tab.preTabIndex;
            }
          });
        }
        this.currentTabIndex = activeName;
        this.tabs = this.tabs.filter((tab) => tab.name !== targetName);
        if (!this.tabs || this.tabs.length === 0) {
          this.currentTabIndex = this.index.name;
        }
      }
    },
    //新增元数据Tab
    addMetedataTab(classType, keyID, refresh) {
      if (classType === 1) this.addEntityTab(keyID, refresh);
      if (classType === 2) this.addPropertyTypeTab(keyID, refresh);
      if (classType === 3) this.addEnumTab(keyID, refresh);
      if (classType === 7) this.addBPSVTab(keyID, refresh);
    },
    //新增实体元数据Tab
    addEntityTab(keyID, refresh) {
      let $this = this;
      this.addBaseMetedataTab(keyID, refresh, function (tab) {
        tab.type = "entity";
        tab.expandrowkeys = [];
        tab.activeNames = ["tabMainAttributes"];
        tab.filterParameter = {
          filterString: "",
          filterOperatorType: 0,
          isOnlyFilterTopLevel: false,
          filterClassType: [-1],
          filterGroupName: ["-"],
        };
        tab.entityAttributesTableMenu = {
          //表格右键
          body: {
            options: [
              [
                {
                  code: "autoExpandAll",
                  name: "自动展开下级",
                  prefixIcon: "el-icon-share",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "collapseAll",
                  name: "收缩所有下级",
                  prefixIcon: "el-icon-collection",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "showCheckboxRecords",
                  name: "显示勾选行",
                  prefixIcon: "el-icon-finished",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "showAllRecords",
                  name: "显示所有行",
                  prefixIcon: "el-icon-c-scale-to-original",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "selectDisplayRecords",
                  name: "勾选当前显示行",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "selectLowerLevelRecords",
                  name: "勾选下级节点",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "selectAllLowerLevelRecords",
                  name: "勾选所有下级节点",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "unSelectDisplayRecords",
                  name: "取消勾选当前显示行",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "unSelectLowerLevelRecords",
                  name: "取消勾选下级节点",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "unSelectAllLowerLevelRecords",
                  name: "取消勾选所有下级节点",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
              ],
            ],
          },
          // 右键区域权限方法设置
          visibleMethod: $this.entityAttributesTableMenuVisibleMethod,
        };
        tab.mainTableLoading = false;
        //补齐Entity元数据
        $this.patchEntityMetedata(tab.metedata);
        tab.isEntityAttributesTableBacktopShow = false;
      });
    },
    //新增属性元数据Tab
    addPropertyTypeTab(keyID, refresh) {
      let $this = this;
      this.addBaseMetedataTab(keyID, refresh, function (tab) {
        tab.type = "propertyType";
        tab.expandrowkeys = [];
        tab.activeNames = ["tabMainAttributes"];
        tab.filterParameter = {
          filterString: "",
          filterOperatorType: 0,
          isOnlyFilterTopLevel: false,
          filterClassType: [-1],
          filterGroupName: ["-"],
        };
        tab.entityAttributesTableMenu = {
          //表格右键
          body: {
            options: [
              [
                {
                  code: "autoExpandAll",
                  name: "自动展开下级",
                  prefixIcon: "el-icon-share",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "collapseAll",
                  name: "收缩所有下级",
                  prefixIcon: "el-icon-collection",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "showCheckboxRecords",
                  name: "显示勾选行",
                  prefixIcon: "el-icon-finished",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "showAllRecords",
                  name: "显示所有行",
                  prefixIcon: "el-icon-c-scale-to-original",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "selectDisplayRecords",
                  name: "勾选当前显示行",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "selectLowerLevelRecords",
                  name: "勾选下级节点",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "selectAllLowerLevelRecords",
                  name: "勾选所有下级节点",
                  prefixIcon: "el-icon-circle-check",
                  visible: true,
                  disabled: false,
                },
              ],
              [
                {
                  code: "unSelectDisplayRecords",
                  name: "取消勾选当前显示行",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "unSelectLowerLevelRecords",
                  name: "取消勾选下级节点",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
                {
                  code: "unSelectAllLowerLevelRecords",
                  name: "取消勾选所有下级节点",
                  prefixIcon: "el-icon-circle-close",
                  visible: true,
                  disabled: false,
                },
              ],
            ],
          },
          // 右键区域权限方法设置
          visibleMethod: $this.entityAttributesTableMenuVisibleMethod,
        };
        tab.mainTableLoading = false;
        //补齐Entity元数据
        $this.patchEntityMetedata(tab.metedata);
        tab.isEntityAttributesTableBacktopShow = false;
      });
    },
    //新增枚举元数据Tab
    addEnumTab(keyID, refresh) {
      let $this = this;
      this.addBaseMetedataTab(keyID, refresh, function (tab) {
        tab.type = "enum";
        tab.activeNames = ["tabMainBase", "tabMainAttributes"];
      });
    },
    //新增BPSV元数据Tab
    addBPSVTab(keyID, refresh, afterInitResolve) {
      let $this = this;
      if (!afterInitResolve)
        afterInitResolve = function (tab) {
          $this.initBPSVEditor(tab);
        };
      this.addBaseMetedataTab(
        keyID,
        refresh,
        function (tab) {
          tab.type = "bpsv";
          tab.expandrowkeys = [];
          tab.activeNames = ["bpsvTabMainTest"];
          tab.currentBPSVTabIndex = "bpsvTabMainTestRequestTab";
          tab.proxyParameter = {
            proxyFullName: tab.metedata.ProxyFullName,
            proxyAssemblyName: tab.metedata.ProxyAssemblyName,
            transferRequestDataByMember: false,
            requestDataAutoExpandLevel: 2,
          };
          tab.proxyAction = {
            loadProxyDataLoading: false,
            totalLoadProxyDataLoading: false,
            proxyDoLoading: false,
          };
          tab.transactionDebug = {
            webSocket: NaN,
            isSetupGlobal: false,
            isSetupProxy: false,
            logTableMenu: {
              //表格右键
              body: {
                options: [
                  [
                    {
                      code: "clearLogData",
                      name: "清除事务日志",
                      prefixIcon: "el-icon-delete",
                      visible: true,
                      disabled: false,
                    },
                  ],
                  [
                    {
                      code: "clearFilter",
                      name: "清除过滤",
                      prefixIcon: "el-icon-delete",
                      visible: true,
                      disabled: false,
                    },
                    {
                      code: "clearSort",
                      name: "清除排序",
                      prefixIcon: "el-icon-delete",
                      visible: true,
                      disabled: false,
                    },
                  ],
                ],
              },
              // 右键区域权限方法设置
              //visibleMethod: $this.entityAttributesTableMenuVisibleMethod
            },
            logData: [],
          };
          tab.proxyDoDebug = {
            webSocket: NaN,
            proxyDoDebugLoading: false,
          };
          tab.openBPSVFileName = "";
        },
        afterInitResolve
      );
    },
    //新增元数据Tab
    addBaseMetedataTab(keyID, refresh, resolve, afterInitResolve) {
      if (this.currentTabIndex == keyID && !refresh) return;
      let tab = this.tabs.find((item) => item.name == keyID);
      if (tab && !refresh) {
        tab.preTabIndex = this.currentTabIndex;
        this.currentTabIndex = tab.name;
        if (afterInitResolve) afterInitResolve(tab);
        return;
      }
      let $this = this;
      if (refresh && tab) this.$set(tab, "isRefreshLoading", true);
      this.getCloneMetedata(keyID, NaN, function (metedata) {
        if (!tab)
          tab = {
            preTabIndex: $this.currentTabIndex,
          };
        tab.name = metedata.Key.ID;
        tab.title = metedata.DisplayName;
        tab.metedata = metedata;
        metedata.tab = tab;
        if (resolve) resolve(tab);
        if (!refresh) {
          $this.tabs.push(tab);
          $this.currentTabIndex = metedata.Key.ID;
          if (afterInitResolve) {
            $this.$nextTick(() => {
              afterInitResolve(tab);
            });
          }
        }
        $this.$set(tab, "isRefreshLoading", false);
      });
    },
    //新增OQLTab
    addOQLTab(srcTab, key, title, oql) {
      let tabType = "oql";
      let keyID = key
        ? key + "-" + tabType
        : srcTab
        ? tabType + "-" + srcTab.name
        : tabType + "-" + Math.uuid();
      title = title ? "OQL:" + title : srcTab ? "OQL:" + srcTab.title : "OQL";
      if (this.currentTabIndex === keyID) return;
      let tab = this.tabs.find((item) => item.name && item.name == keyID);
      if (tab) {
        tab.preTabIndex = this.currentTabIndex;
        this.currentTabIndex = tab.name;
        return;
      }
      let $this = this;
      tab = {
        name: keyID,
        type: tabType,
        title: title,
        srcTab: srcTab,
        preTabIndex: $this.currentTabIndex,
        currentOQLTabIndex: "oqlTabMainOQLTab",
        activeNames: ["oqlTabMainOQL"],
        oqlAction: {
          convertOqlToSqlLoading: false,
          runOqlLoading: false,
        },
        defaultPageParamter: {
          pageIndex: 0,
          pageSize: 20,
          totalCount: 0,
          totalPage: 0,
        },
        runOQLResult: {
          pageParamter: {
            pageIndex: 0,
            pageSize: 20,
            totalCount: 0,
            totalPage: 0,
          },
          queryData: [],
        },
        resultPageSizes: [20, 50, 100, 200, 500, 1000],
        resultFixedColumns: [],
        oqlParameter: {
          expandEntityTable: false, //扩开表
          createTempTableWhenCreateSQL: false, //生成SQL时，生成临时表
          useBusinessKeyForParams: false, //实体主键作为过滤条件
          useEngcolumnAliasName: false, //列名采用英文
          sortFieldByRowIndex: false, //按行顺序排列字段
          reserveFilterWhenReBuildOQL: true, //重构OQL保留过滤条件
        },
      };
      $this.tabs.push(tab);
      $this.currentTabIndex = keyID;
      $this.$nextTick(() => {
        if (!oql) {
          if (srcTab && srcTab.type === "entity")
            oql = $this.createOQLFromEntityTab(srcTab, tab.oqlParameter);
          if (srcTab && srcTab.type === "enum")
            oql = $this.createOQLFromEnumTab(srcTab);
        }
        $this.initOQLEditor(tab, oql);
      });
    },
    //添加自定义值集OQL
    addValueSetOQLTab(valueSetDef) {
      let oql = ""
        .concat("select\r\n")
        .concat("  DefineValue.Code as 编码,\r\n")
        .concat("  DefineValue.Name as 名称,\r\n")
        .concat("  DefineValue.Effective.IsEffective as 生效,\r\n")
        .concat("  DefineValue.Effective.EffectiveDate as 生效日期,\r\n")
        .concat("  DefineValue.Effective.DisableDate as 失效日期,\r\n")
        .concat("  ValueSetDef.Code as 值集定义编码,\r\n")
        .concat("  ValueSetDef.Name as 值集定义名称\r\n")
        .concat("from\r\n")
        .concat(
          "  UFIDA::U9::Base::FlexField::ValueSet::DefineValue DefineValue\r\n"
        )
        .concat(
          "  inner join UFIDA::U9::Base::FlexField::ValueSet::ValueSetDef ValueSetDef on DefineValue.ValueSetDef = ValueSetDef.ID\r\n"
        )
        .concat("where\r\n")
        .concat("  ValueSetDef.Code = '" + valueSetDef.Code + "'\r\n")
        .concat("order by\r\n")
        .concat("  DefineValue.Code");
      this.addOQLTab(
        NaN,
        "ValueSetDef-" + valueSetDef.Code,
        "值集-" + valueSetDef.Name,
        oql
      );
    },
    //通过实体枚举生成OQL
    createOQLFromEnumTab(tab) {
      if (!tab) return;
      let metedata = tab.metedata;
      return ""
        .concat("select\r\n")
        .concat("  ExtEnumValue.Code as 枚举编码,\r\n")
        .concat("  ExtEnumValue.Name as 枚举名称,\r\n")
        .concat("  ExtEnumValue.EValue as 枚举值,\r\n")
        .concat("  ExtEnumValue.IsSystem as 是否系统预制,\r\n")
        .concat("  ExtEnumType.Code as 枚举类型编码,\r\n")
        .concat("  ExtEnumType.Name as 枚举类型名称\r\n")
        .concat("from\r\n")
        .concat("  UFIDA::UBF::MD::Business::ExtEnumValue ExtEnumValue\r\n")
        .concat(
          "  inner join UFIDA::UBF::MD::Business::ExtEnumType ExtEnumType on ExtEnumValue.ExtEnumType = ExtEnumType.ID\r\n"
        )
        .concat("where\r\n")
        .concat("  ExtEnumType.Code = '" + metedata.Key.FullName + "'\r\n")
        .concat("order by\r\n")
        .concat("  ExtEnumValue.EValue");
    },
    //获取当前Tab
    getCurrentTab(pageSize) {
      let $this = this;
      return $this.tabs.find((item) => item.name == $this.currentTabIndex);
    },
    //#endregion
    //#region 首页
    //查询元数据
    queryMetedata() {
      let parameter = {
        classType: this.index.queryForm.classType.join(","),
        queryString: this.index.queryForm.queryString,
        like: this.index.queryForm.likeChecked,
      };
      //console.log('parameter', parameter);
      this.index.queryForm.loading = true;
      let $this = this;
      this.api().queryMetedata(parameter, function (res) {
        //console.log("查询结果", res);
        $this.index.queryForm.loading = false;
        if (res.code === 0) {
          $this.index.queryExpandRowKeys = [];
          $this.index.queryResult = res.data.map((item, index) => {
            item.metedata = {};
            item.loadMetedata = false;
            item.activeNames = [];
            return item;
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //聚焦元数据
    focusMetedata(classType, queryString) {
      let $this = this;
      this.index.queryForm.loading = true;
      let parameter = {
        classType: classType,
        queryString: queryString,
        focus: true,
      };
      this.api().queryMetedata(parameter, function (res) {
        $this.index.queryForm.loading = false;
        if (res.code === 0) {
          $this.index.queryExpandRowKeys = [];
          $this.index.queryResult = res.data.map((item, index) => {
            item.metedata = {};
            item.loadMetedata = false;
            return item;
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //首页查询结果展开变化
    indexQueryResultExpandChange(row, expandedRows) {
      if (!row.loadMetedata) {
        let keyID = row.ID;
        var $this = this;
        this.getCloneMetedata(keyID, NaN, function (metedata) {
          metedata.expandrowkeys = [];
          metedata.isAutoExpandLoading = false;
          $this.patchEntityMetedata(metedata);
          $this.$set(row, "metedata", metedata);
          $this.$set(row, "loadMetedata", true);
        });
      }
    },
    //首页查询结果行双击事件
    onIndexQueryResultDblClick(row, column, event) {
      let $this = this;
      let rowRef = $this.$refs[row.ID];
      if (!rowRef) return;
      const expandIcon = rowRef.parentNode.parentNode.parentNode.querySelector(
        ".el-table__expand-icon"
      );
      if (expandIcon) expandIcon.click();
    },
    //是否存在种类关联
    isExistAssociationsByKind(metedata, kind) {
      if (!metedata || !metedata.Associations) return false;
      return metedata.Associations.find(
        (association) => association.Kind === kind
      );
    },
    //按种类过滤关联
    filterAssociationsByKind(metedata, kind) {
      if (!metedata || !metedata.Associations) return [];
      return kind
        ? metedata.Associations.filter(
            (association) => association.Kind === kind
          )
        : metedata.Associations;
    },
    //自动展开
    autoExpandEntityAssociationTable(metedata) {
      let tableRef = this.$refs[metedata.ID + "_TableRef"];
      if (!tableRef) return;
      let collapseRef = this.$refs[metedata.ID + "_ChildEntityCollapseRef"];
      if (!tableRef || !collapseRef) return;
      if (!collapseRef.activeNames) collapseRef.activeNames = [];
      if (collapseRef.activeNames.indexOf("childEntity") < 0)
        collapseRef.activeNames.push("childEntity");
      let $this = this;
      metedata.isAutoExpandLoading = true;
      let associations = this.filterAssociationsByKind(metedata, 1);
      let needExpandAssociations = [];
      associations.forEach((association) => {
        if (association.ChildEntityHasChildren)
          this.loadChildEntityAssociation(association, needExpandAssociations);
      });
      let callback = function () {
        //console.log("needExpandAssociations", needExpandAssociations);
        if (
          needExpandAssociations.filter(
            (needExpandAssociation) => needExpandAssociation.loading == true
          ).length > 0
        ) {
          setTimeout(callback, 50);
        } else {
          console.log("全部完成");
          associations.forEach((association) => {
            if (association.ChildEntityHasChildren)
              $this.expandChildEntityAssociation(association);
          });
          metedata.isAutoExpandLoading = false;
        }
      };
      callback.call(this);
    },
    //自动收缩
    autoCollapseEntityAssociationTable(metedata) {
      let $this = this;
      let associations = this.filterAssociationsByKind(metedata, 1);
      associations.forEach((association) => {
        if (association.ChildEntityHasChildren)
          $this.collapseChildEntityAssociation(association);
      });
    },
    //收缩子实体关联
    collapseChildEntityAssociation(association) {
      let $this = this;
      let rowRef = $this.$refs[association.associationID];
      if (!rowRef) return;
      const list = rowRef.parentNode.querySelectorAll(".el-table__expand-icon");
      if (
        list.length > 0 &&
        list[0].className.includes("el-table__expand-icon--expanded")
      )
        list[0].click();
      $this.$nextTick(() => {
        if (association.children && association.children.length > 0) {
          association.children.forEach((childAssociation) => {
            if (childAssociation.ChildEntityHasChildren)
              $this.collapseChildEntityAssociation(childAssociation);
          });
        }
      });
    },
    //加载子实体关联
    loadChildEntityAssociation(association, needExpandAssociations) {
      let $this = this;
      if (association.children && association.children.length > 0) {
        association.children.forEach((childAssociation) => {
          if (childAssociation.ChildEntityHasChildren)
            $this.loadChildEntityAssociation(
              childAssociation,
              needExpandAssociations
            );
        });
      } else {
        //实体或属性
        let keyID = association.ChildEntityKey.ID;
        let needExpandAssociation = {
          id: association.associationID,
          name: association.Name,
          loading: true,
        };
        needExpandAssociations.push(needExpandAssociation);
        this.getCloneMetedata(keyID, NaN, function (metedata) {
          let currentMetedata = metedata;
          //补齐Entity元数据关联
          $this.patchEntityMetedata(currentMetedata, NaN, association);
          association.children = $this.filterAssociationsByKind(
            currentMetedata,
            1
          );
          association.children.forEach((childAssociation) => {
            if (childAssociation.ChildEntityHasChildren)
              $this.loadChildEntityAssociation(
                childAssociation,
                needExpandAssociations
              );
          });
          needExpandAssociation.loading = false;
        });
      }
    },
    //展开子实体关联
    expandChildEntityAssociation(association) {
      let $this = this;
      let rowRef = $this.$refs[association.associationID];
      if (!rowRef) return;
      const list = rowRef.parentNode.querySelectorAll(".el-table__expand-icon");
      if (
        list.length > 0 &&
        !list[0].className.includes("el-table__expand-icon--expanded")
      )
        list[0].click();
      $this.$nextTick(() => {
        if (association.children && association.children.length > 0) {
          association.children.forEach((childAssociation) => {
            if (childAssociation.ChildEntityHasChildren)
              $this.expandChildEntityAssociation(childAssociation);
          });
        }
      });
    },
    //获取表格行样式名称
    getAssociationTableRowClassName({ row, rowIndex }) {
      row.rowIndex = rowIndex;
      return "";
    },
    //当上下文信息展示
    getCurrentContext(resolve) {
      let $this = this;
      this.api().getCurrentContext(function (res) {
        if (res.code === 0) {
          $this.index.contextData = res.data;
          if (resolve) resolve(res.data);
        } else {
          $this.index.contextData = NaN;
        }
      });
    },
    //获取是否启用自定义代理
    getIsSetupCustomProxy() {
      let $this = this;
      this.api().isSetupCustomProxy(function (res) {
        if (res.code === 0) {
          $this.isSetupCustomProxy = res.setupCustomProxy;
        } else {
          $this.isSetupCustomProxy = false;
        }
      });
    },
    //初始化WordCloud
    initChartWordCloud() {
      let $this = this;
      let chart = echarts.init($this.$refs.indexWordCloud);
      chart.setOption({
        series: [
          {
            type: "wordCloud",
            /*要绘制的“云”的形状。可以是为回调函数，或一个关键字。可用的形状有(circle)圆形(默认)、(cardioid)心形，(diamond)菱形，(triangle-forward)三角形向前，(triangle)三角形，(pentagon)五边形和(star)星形。*/
            //shape: "triangle",
            //用来调整词之间的距离
            gridSize: 18,
            //用来调整字的大小范围
            // Text size range which the value in data will be mapped to.
            // Default to have minimum 12px and maximum 60px size.
            sizeRange: [12, 30],
            // Text rotation range and step in degree. Text will be rotated randomly in range [-90,                                                                             90] by rotationStep 45
            //用来调整词的旋转方向，，[0,0]--代表着没有角度，也就是词为水平方向，需要设置角度参考注释内容
            //rotationRange: [-45, 0, 45, 90],
            //rotationRange: [ 0,90],
            rotationRange: [0, 0],
            // 执行布局动画。当有大量的单词时，关闭它会导致UI阻塞。
            //layoutAnimation: true,
            //随机生成字体颜色
            // maskImage: maskImage,
            textStyle: {
              color: function () {
                return (
                  "rgb(" +
                  Math.round(Math.random() * 255) +
                  ", " +
                  Math.round(Math.random() * 255) +
                  ", " +
                  Math.round(Math.random() * 255) +
                  ")"
                );
              },
            },
            emphasis1: {
              focus: "self",
              textStyle: {
                textShadowBlur: 10,
                textShadowColor: "#333",
              },
            },
            //位置相关设置
            // Folllowing left/top/width/height/right/bottom are used for positioning the word cloud
            // Default to be put in the center and has 75% x 80% size.
            left: "center",
            top: "center",
            right: null,
            bottom: null,
            width: "200%",
            height: "200%",
            //数据
            data: wordCloudList,
          },
        ],
      });
      // 点击某个字
      chart.on("click", function (params) {
        //console.log("chart----click---:", params, "------", params.data);
        if (params && params.data) {
          let data = params.data;
          if (data.code) {
            $this.index.queryForm.queryString = data.code;
            $this.index.queryForm.likeChecked = false;
            if ($this.index.queryForm.classType.indexOf("1") < 0)
              $this.index.queryForm.classType.push(1);
            $this.queryMetedata();
          }
        }
      });
      // // 指定图表的配置项和数据
      // var option = {
      //   title: {
      //     text: "ECharts 入门示例",
      //   },
      //   tooltip: {},
      //   legend: {
      //     data: ["销量"],
      //   },
      //   xAxis: {
      //     data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
      //   },
      //   yAxis: {},
      //   series: [
      //     {
      //       name: "销量",
      //       type: "bar",
      //       data: [5, 20, 36, 10, 10, 20],
      //     },
      //   ],
      // };

      // // 使用刚指定的配置项和数据显示图表。
      // chart.setOption(option);
      // chart.resize();
    },
    //#endregion
    //#region 实体页
    //#region 显示
    onEntityRefresh(tab) {
      let tableRef = this.getEntityAttributesTableRef(tab);
      //设置实体过滤
      this.setEntityAttributesTableFilter(tableRef, false);
      this.onRefresh(tab);
    },
    //获取属性的数量
    getTabAttributesCount(tab) {
      let count = 0;
      XEUtils.eachTree(
        tab.metedata.Attributes,
        (attribute) => {
          count++;
        },
        { children: "childrenAttributes" }
      );
      return count;
    },
    //获取实体属性类型名称
    getEntityAttributeDataTypeName(row) {
      if (!row) return;
      let enums = this.enums;
      if (row.DataTypeFlag === 0) {
        if (!row.DescFlexFieldDef) {
          return row.DataTypeKey && row.DataTypeKey.FullName
            ? row.DataTypeKey.FullName +
                (row.DataTypeKey.FullName === "System.String"
                  ? "(" + row.Length + ")"
                  : row.DataTypeKey.FullName === "System.Decimal"
                  ? "(" + row.Precision + "," + row.Scale + ")"
                  : "")
            : "";
        }
        if (row.DescFlexFieldDef.ValueSetDef.ValidateType === 1) {
          return row.DescFlexFieldDef.ValueSetDef.EntityType &&
            row.DescFlexFieldDef.ValueSetDef.EntityType.FullName
            ? row.DescFlexFieldDef.ValueSetDef.EntityType.FullName
            : "Entity";
        }
        if (row.DescFlexFieldDef.ValueSetDef.ValidateType === 2) {
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 1) {
            return (
              this.getEnumOptionName(
                enums.ValueSetDefValueTypeEnum,
                row.DescFlexFieldDef.ValueSetDef.ValueType
              ) +
              "(" +
              row.DescFlexFieldDef.ValueSetDef.MinValue +
              "~" +
              row.DescFlexFieldDef.ValueSetDef.MaxValue +
              ")"
            );
          }
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 2) {
            return (
              this.getEnumOptionName(
                enums.ValueSetDefValueTypeEnum,
                row.DescFlexFieldDef.ValueSetDef.ValueType
              ) +
              "(" +
              row.DescFlexFieldDef.ValueSetDef.Length +
              ")"
            );
          }
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 3) {
            return (
              this.getEnumOptionName(
                enums.ValueSetDefValueTypeEnum,
                row.DescFlexFieldDef.ValueSetDef.ValueType
              ) +
              "(" +
              row.DescFlexFieldDef.ValueSetDef.MinValue +
              "~" +
              row.DescFlexFieldDef.ValueSetDef.MaxValue +
              ")"
            );
          }
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 4) {
            return (
              this.getEnumOptionName(
                enums.ValueSetDefValueTypeEnum,
                row.DescFlexFieldDef.ValueSetDef.ValueType
              ) +
              row.DescFlexFieldDef.ValueSetDef.Pricision +
              "位小数" +
              "(" +
              row.DescFlexFieldDef.ValueSetDef.MinValue +
              "~" +
              row.DescFlexFieldDef.ValueSetDef.MaxValue +
              ")"
            );
          }
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 5) {
            return this.getEnumOptionName(
              enums.ValueSetDefValueTypeEnum,
              row.DescFlexFieldDef.ValueSetDef.ValueType
            );
          }
          if (row.DescFlexFieldDef.ValueSetDef.ValueType === 6) {
            return (
              this.getEnumOptionName(
                enums.ValueSetDefValueTypeEnum,
                row.DescFlexFieldDef.ValueSetDef.ValueType
              ) +
              "(" +
              row.DescFlexFieldDef.ValueSetDef.MinValue +
              "~" +
              row.DescFlexFieldDef.ValueSetDef.MaxValue +
              ")"
            );
          }
        }
        if (row.DescFlexFieldDef.ValueSetDef.ValidateType === 3) {
          return (
            this.getEnumOptionName(
              enums.ValueSetDefValidateTypeEnum,
              row.DescFlexFieldDef.ValueSetDef.ValidateType
            ) +
            "(" +
            row.DescFlexFieldDef.ValueSetDef.Code +
            "/" +
            row.DescFlexFieldDef.ValueSetDef.Name +
            ")"
          );
        }
        if (row.DescFlexFieldDef.ValueSetDef.ValidateType === 4) {
          return row.DescFlexFieldDef.ValueSetDef.EnumType &&
            row.DescFlexFieldDef.ValueSetDef.EnumType.FullName
            ? row.DescFlexFieldDef.ValueSetDef.EnumType.FullName
            : "enum";
        }
      }
      if (row.DataTypeFlag === 1) {
        return row.DataTypeKey && row.DataTypeKey.FullName
          ? row.DataTypeKey.FullName
          : "Entity";
      }
      if (row.DataTypeFlag === 2) {
        return row.DataTypeKey && row.DataTypeKey.FullName
          ? row.DataTypeKey.FullName
          : "PropertyType";
      }
      if (row.DataTypeFlag === 3) {
        return row.DataTypeKey && row.DataTypeKey.FullName
          ? row.DataTypeKey.FullName
          : "Enum";
      }
      if (row.DataTypeFlag === 4) {
        return row.DataTypeKey && row.DataTypeKey.FullName
          ? row.DataTypeKey.FullName
          : "Composition";
      }
      return row.DataTypeKey && row.DataTypeKey.Name
        ? row.DataTypeKey.Name
        : "未知";
    },
    //加载实体子属性方法
    loadEntityChildrenAttributesMethod({ row }) {
      let attribute = row;
      if (
        attribute.DataTypeFlag !== 1 &&
        attribute.DataTypeFlag !== 2 &&
        attribute.DataTypeFlag !== 4
      )
        return;
      //实体或属性
      let keyID = attribute.DataTypeKey.ID;
      let $this = this;
      let parentFullName =
        attribute.DataTypeKey.FullName ===
        this.constObj.descFlexSegmentsFullName
          ? attribute.metedata.Key.FullName
          : NaN;
      return new Promise((resolve) => {
        if (attribute.childrenAttributes) {
          resolve(attribute.childrenAttributes);
        } else {
          this.getCloneMetedata(keyID, parentFullName, function (metedata) {
            //补齐Entity元数据属性
            $this.patchEntityMetedata(metedata, attribute);
            resolve(metedata.Attributes);
          });
        }
      });
    },
    //实体属性表Cell样式
    onEntityAttributesTableCellStyle({ row, column, rowIndex, columnIndex }) {
      //console.log('onEntityAttributesCellStyle:', row.fullExpression)
      this.$nextTick(() => {
        let attribute = row;
        if (column.property && column.property === "Name") {
          let rowNameRef = this.getEntityAttributesRowNameRef(attribute);
          if (!rowNameRef) return;
          let vxeCellDom = rowNameRef.parentNode;
          while (vxeCellDom) {
            if ($(vxeCellDom).hasClass("vxe-body--column")) break;
            vxeCellDom = vxeCellDom.parentNode;
          }
          if (!vxeCellDom) return;
          if (!vxeCellDom.querySelector) return;
          let indexID = "index_" + attribute.attributeID;
          let indexDiv = vxeCellDom.querySelector("#" + indexID);
          if (indexDiv) return;
          //console.log(rowIndex);
          //手动创建节点,实现间接挂载
          var indexNode = document.createElement("div");
          indexNode.setAttribute("id", indexID);
          vxeCellDom.insertBefore(indexNode, vxeCellDom.childNodes[0]);
          let $this = this;
          // 创建构造器
          var index = Vue.extend({
            template: `<div :id="'index_'+row.attributeID" class="indexRowAttribute">
                                        <span v-if="row.hasChildren||row.level>1" style="float: left;"
                                            v-for="level in row.level">
                                            <span class="el-link" style="color: #409EFF;">{{level===1?"":"."}}</span>
                                            <el-tooltip effect="light" :open-delay="1000" :content="getRowIndexViewString(row,level)" placement="top">
                                                <el-link type="primary" class="indexLink"
                                                    :underline="level!==row.level"
                                                    v-on:click.stop="onRowIndexClick(row,level,$event)">{{level}}</el-link>
                                            </el-tooltip>
                                        </span>
                                    </div>`,
            data: function () {
              return {
                row: row,
              };
            },
            methods: {
              //获取行索引显示字符
              getRowIndexViewString(attribute, level) {
                if (!attribute || !level) return;
                let fullExpressionDisplayName =
                  attribute.fullExpressionDisplayName;
                let names = fullExpressionDisplayName.split(".");
                return names.slice(0, level + 1).join(".");
              },
              onRowIndexClick(row, level, evnt) {
                let tab = row.metedata.tab;
                let tableRef = $this.getEntityAttributesTableRef(tab);
                let targetRow;
                for (let i = level - 1; i < row.level; i++) {
                  if (targetRow) {
                    targetRow = targetRow.parentAttribute;
                  } else {
                    targetRow = row;
                  }
                }
                evnt.preventDefault();
                var params = {
                  $table: tableRef,
                  row: targetRow,
                };
                tableRef.scrollToRow(targetRow).then(function () {
                  return tableRef.triggerCurrentRowEvent(evnt, params);
                });
              },
            },
          });
          //创建 index 实例，并挂载到一个元素上。
          let indexRef = new index().$mount("#" + indexID);
          if (row.level > 1) {
            let cellTreeNodeDom = rowNameRef.parentNode.parentNode;
            let width = indexRef.$el.offsetWidth - 10;
            cellTreeNodeDom.style.paddingLeft = width + "px";
          }
        }
      });
    },
    //实体属性表滚动
    onEntityAttributesTableScroll(tab, body) {
      if (body && body.scrollTop) {
        tab.isEntityAttributesTableBacktopShow = body.scrollTop > 50;
      }
      //OQL表达式窗口
      if (
        this.$refs.oqlExpressionPopover &&
        this.$refs.oqlExpressionPopover.showPopper
      ) {
        this.$refs.oqlExpressionPopover.doClose();
      }
      //公式表达式窗口
      if (
        this.$refs.formulaExpressionPopover &&
        this.$refs.formulaExpressionPopover.showPopper
      ) {
        this.$refs.formulaExpressionPopover.doClose();
      }
    },
    //实体属性表回到顶端
    onEntityAttributesTableBacktop(tab) {
      let tableRef = this.getEntityAttributesTableRef(tab);
      tableRef.scrollTo(null, 0).then(() => {
        tab.isEntityAttributesTableBacktopShow = false;
      });
    },
    //自动展开实体属性表
    autoExpandEntityAttributesTable(tab, attribute) {
      if (!tab) return;
      //let v = XEUtils.isNaN(tab);
      let metedata = tab.metedata;
      let $this = this;
      let needLoadAttributes = [];
      tab.mainTableLoading = true;
      if (attribute) {
        this.autoLoadAttributeChildAttributes(attribute, needLoadAttributes);
      } else {
        metedata.Attributes.forEach((childAttribute) => {
          this.autoLoadAttributeChildAttributes(
            childAttribute,
            needLoadAttributes
          );
        });
      }
      let tableRef = this.getEntityAttributesTableRef(tab);
      let callback = function () {
        //console.log("needLoadAttributes", needLoadAttributes);
        if (
          needLoadAttributes.filter(
            (needLoadAttribute) =>
              needLoadAttribute.isLoadingChildAttribute == true
          ).length > 0
        ) {
          setTimeout(callback, 50);
        } else {
          //console.log("加载全部完成");
          let attributes = [];
          if (attribute) {
            attributes.push(attribute);
          } else {
            attributes = metedata.Attributes;
          }
          let needExpandAttributes = [];
          XEUtils.eachTree(
            attributes,
            (attribute) => {
              if (
                attribute.childrenAttributes &&
                attribute.childrenAttributes.length > 0
              ) {
                needExpandAttributes.push(attribute);
              }
            },
            { children: "childrenAttributes" }
          );
          if (attribute) {
            if (needExpandAttributes.indexOf(attribute) < 0)
              needExpandAttributes.unshift(attribute);
            $this.expandEntityAttributesTreeNode(
              tableRef,
              needExpandAttributes,
              attribute.level
            );
          } else {
            $this.expandEntityAttributesTreeNode(
              tableRef,
              needExpandAttributes,
              1
            );
          }
          tab.mainTableLoading = false;
        }
      };
      callback.call(this);
    },
    //自动加载属性的子属性
    autoLoadAttributeChildAttributes(attribute, needExpandAttributes) {
      if (attribute.DataTypeKind !== 1 && attribute.DataTypeFlag !== 2) return;
      let tab = attribute.metedata.tab;
      needExpandAttributes.push(attribute);
      let $this = this;
      if (
        attribute.childrenAttributes &&
        attribute.childrenAttributes.length > 0
      ) {
        attribute.childrenAttributes.forEach((childAttribute) => {
          if (
            childAttribute.DataTypeKind === 1 ||
            childAttribute.DataTypeFlag === 2
          )
            $this.autoLoadAttributeChildAttributes(
              childAttribute,
              needExpandAttributes
            );
        });
      } else {
        //实体或属性
        let keyID = attribute.DataTypeKey.ID;
        attribute.isLoadingChildAttribute = true;
        let parentFullName =
          attribute.DataTypeKey.FullName ===
          this.constObj.descFlexSegmentsFullName
            ? attribute.metedata.Key.FullName
            : NaN;
        this.getCloneMetedata(keyID, parentFullName, function (metedata) {
          let currentMetedata = metedata;
          //补齐Entity元数据
          $this.patchEntityMetedata(currentMetedata, attribute);
          currentMetedata.Attributes.forEach((childAttribute) => {
            if (
              childAttribute.DataTypeKind === 1 ||
              childAttribute.DataTypeFlag === 2
            )
              $this.autoLoadAttributeChildAttributes(
                childAttribute,
                needExpandAttributes
              );
          });
          attribute.isLoadingChildAttribute = false;
        });
      }
    },
    //展开实体属性表树节点
    expandEntityAttributesTreeNode(tableRef, needExpandAttributes, level) {
      let $this = this;
      let levelNeedExpandAttributes = needExpandAttributes.filter(
        (attribute) => attribute.level === level
      );
      if (levelNeedExpandAttributes.length == 0) return;
      tableRef.setTreeExpand(levelNeedExpandAttributes, true).then(function () {
        $this.expandEntityAttributesTreeNode(
          tableRef,
          needExpandAttributes,
          level + 1
        );
      });
    },
    //全部收缩
    collapseAllEntityAttributesTable(tab) {
      let tableRef = this.getEntityAttributesTableRef(tab);
      tableRef.setAllTreeExpand(false);
    },
    //焦点实体属性表行
    focusEntityAttributesTableRow(tab, attribute, evnt) {
      let tableRef = this.getEntityAttributesTableRef(tab);
      if (!tableRef) return;
      //清除实体过滤
      this.setEntityAttributesTableFilter(tableRef, false);
      evnt.preventDefault();
      tableRef.updateData().then(() => {
        var params = {
          $table: tableRef,
          row: attribute,
        };
        tableRef.scrollToRow(attribute).then(function () {
          //tableRef.setCurrentRow(attribute);
          return tableRef.triggerCurrentRowEvent(evnt, params);
        });
      });
    },
    //同步组合名称
    syncFieldCombineName(attribute) {
      if (!attribute) return;
      if (!attribute.DescFlexFieldDef) return;
      if (!attribute.parentAttribute) return;
      let entityFullName = attribute.parentAttribute.metedata.FullName;
      let descFieldName = attribute.parentAttribute.Name.concat(
        "_",
        attribute.Name
      );
      //debugger;
      console.log(entityFullName, descFieldName);
      let parameter = {
        entityFullName: entityFullName,
        descFieldName: descFieldName,
      };
      attribute.syncFieldCombineNameLoading = true;
      let $this = this;
      this.api().syncFieldCombineName(parameter, function (res) {
        if (res.code === 0) {
          $this.$message({
            message: "同步组合名称成功",
            type: "success",
            duration: 1000,
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: 5000,
          });
        }
        attribute.syncFieldCombineNameLoading = false;
      });
    },
    //实体属性表行双击事件
    onEntityAttributesTableCellDblclick({
      row,
      rowIndex,
      $rowIndex,
      column,
      columnIndex,
      $columnIndex,
      $event,
    }) {
      let attribute = row;
      if (!attribute || !attribute.hasChildren) return;
      let tab = attribute.metedata.tab;
      let tableRef = this.getEntityAttributesTableRef(tab);
      tableRef.toggleTreeExpand(attribute);
    },
    //#endregion
    //#region 排序/过滤
    //实体属性排序方法
    entityAttributesSortMethod({ data, sortList }) {
      const sortItem = sortList[0];
      const { property, order } = sortItem;
      let $this = this;
      let list = [];
      if (order === "asc" || order === "desc") {
        if (property === "Name") {
          list = data.sort((a, b) => {
            return $this.sortStringMethod(a.Name, b.Name);
          });
        }
        if (property === "DisplayName") {
          list = data.sort((a, b) => {
            return $this.sortStringMethod(a.DisplayName, b.DisplayName);
          });
        }
        if (property === "DataType") {
          list = data.sort((a, b) => {
            let aDataTypeName = $this.getEntityAttributeDataTypeName(a);
            let bDataTypeName = $this.getEntityAttributeDataTypeName(b);
            return $this.sortStringMethod(aDataTypeName, bDataTypeName);
          });
        }
        if (property === "DataTypeFlag") {
          list = data.sort((a, b) => {
            return a.DataTypeFlag - b.DataTypeFlag;
          });
        }
        if (property === "GroupName") {
          list = data.sort((a, b) => {
            return $this.sortStringMethod(a.GroupName, b.GroupName);
          });
        }
        if (property === "IsBusinessKey") {
          list = data.sort((a, b) => {
            let aValue = a.IsBusinessKey ? a.IsBusinessKey : false;
            let bValue = b.IsBusinessKey ? b.IsBusinessKey : false;
            return aValue - bValue;
          });
        }
        if (property === "IsNullable") {
          list = data.sort((a, b) => {
            let aValue = a.IsNullable ? a.IsNullable : false;
            let bValue = b.IsNullable ? b.IsNullable : false;
            return aValue - bValue;
          });
        }
      }
      if (order === "desc") {
        list.reverse();
      }
      return list;
    },
    //实体表过滤方法
    entityAttributesTableFilterMethod({ values, row, column }) {
      return row.isShow === 1;
    },
    //获取分组数组
    getGroupNameOptions(tab) {
      let options = [];
      let metedata = tab.metedata;
      if (!metedata || !metedata.Attributes || metedata.Attributes.length === 0)
        return options;
      let groupNames = [];
      if (tab.filterParameter.isOnlyFilterTopLevel) {
        metedata.Attributes.forEach((attribute, index) => {
          if (groupNames.indexOf(attribute.GroupName) < 0) {
            groupNames.push(attribute.GroupName);
          }
        });
      } else {
        XEUtils.eachTree(
          metedata.Attributes,
          (attribute) => {
            if (groupNames.indexOf(attribute.GroupName) < 0) {
              groupNames.push(attribute.GroupName);
            }
          },
          { children: "childrenAttributes" }
        );
      }
      groupNames.sort(this.sortStringMethod);
      groupNames.forEach((groupName, index) => {
        options.push({ label: groupName, key: groupName, value: groupName });
      });
      return options;
    },
    //当类型选择变化
    onClassTypeSelectChange(tab) {
      let filterClassType = tab.filterParameter.filterClassType;
      if (!filterClassType || filterClassType.length === 0)
        tab.filterParameter.filterClassType = [-1];
      if (filterClassType[filterClassType.length - 1] === -1) {
        tab.filterParameter.filterClassType = [-1];
      } else {
        let index = filterClassType.indexOf(-1);
        if (index >= 0) {
          tab.filterParameter.filterClassType.splice(index, 1);
        }
      }
      let $this = this;
      // this.$nextTick(() => {
      //     $this.onEntityAttributesTableFilterChange(tab);
      // });
      //当实体属性表过滤变化
      $this.onEntityAttributesTableFilterChange(tab);
    },
    //当过滤分组变化
    onGroupNameSelectChange(tab) {
      let filterGroupName = tab.filterParameter.filterGroupName;
      if (!filterGroupName || filterGroupName.length === 0)
        tab.filterParameter.filterGroupName = ["-"];
      if (filterGroupName[filterGroupName.length - 1] === "-") {
        tab.filterParameter.filterGroupName = ["-"];
      } else {
        let index = filterGroupName.indexOf("-");
        if (index >= 0) {
          tab.filterParameter.filterGroupName.splice(index, 1);
        }
      }
      this.onEntityAttributesTableFilterChange(tab);
    },
    //当实体属性表过滤变化
    onEntityAttributesTableFilterChange(tab) {
      let $this = this;
      $this.resetAllAttributesShowStatus(tab);
      let attributes = $this.getEntityAttributesTableFilterResult(tab);
      attributes.forEach((attribute) => {
        attribute.isShow = 1;
      });
      let tableRef = this.getEntityAttributesTableRef(tab);
      //设置实体过滤
      this.setEntityAttributesTableFilter(tableRef, true);
      //更新数据
      tableRef.updateData();
    },
    //重置属性过滤
    resetAllAttributesShowStatus(tab) {
      XEUtils.eachTree(
        tab.metedata.Attributes,
        (attribute) => {
          attribute.isShow = 0;
        },
        { children: "childrenAttributes" }
      );
    },
    //设置实体过滤值
    setEntityAttributesTableFilter(tableRef, checked) {
      if (!tableRef) return;
      const isShowColumn = tableRef.getColumnByField("isShow");
      const showOption = isShowColumn.filters[1];
      showOption.checked = checked;
    },
    //获取实体属性表过滤结果
    getEntityAttributesTableFilterResult(tab) {
      let metedata = tab.metedata;
      let filterParameter = tab.filterParameter;
      let tableData = [];
      let $this = this;
      metedata.Attributes.forEach((attribute) => {
        if (filterParameter.isOnlyFilterTopLevel) {
          if ($this.isAttributeMatchCondition(attribute, filterParameter)) {
            tableData.push(attribute);
            let childMatchAttributes = $this.getChildAttribuesMatchCondition(
              attribute,
              filterParameter
            );
            tableData.push.apply(tableData, childMatchAttributes);
          }
        } else {
          let childMatchAttributes = $this.getChildAttribuesMatchCondition(
            attribute,
            filterParameter
          );
          if (
            childMatchAttributes.length > 0 ||
            $this.isAttributeMatchCondition(attribute, filterParameter)
          ) {
            tableData.push(attribute);
            tableData.push.apply(tableData, childMatchAttributes);
          }
        }
      });
      //console.log('tableData:', tableData.length);
      return tableData;
    },
    //获取符合条件的子属性
    getChildAttribuesMatchCondition(parentAttribute, filterParameter) {
      let matchAttributes = [];
      let $this = this;
      if (
        parentAttribute.childrenAttributes &&
        parentAttribute.childrenAttributes.length > 0
      ) {
        parentAttribute.childrenAttributes.forEach((attribute) => {
          if ($this.isAttributeMatchCondition(attribute, filterParameter)) {
            matchAttributes.push(attribute);
            let childMatchAttributes = $this.getChildAttribuesMatchCondition(
              attribute,
              filterParameter
            );
            if (childMatchAttributes.length > 0)
              matchAttributes.push.apply(matchAttributes, childMatchAttributes);
          } else {
            let childMatchAttributes = $this.getChildAttribuesMatchCondition(
              attribute,
              filterParameter
            );
            if (childMatchAttributes.length > 0) {
              matchAttributes.push(attribute);
              matchAttributes.push.apply(matchAttributes, childMatchAttributes);
            }
          }
        });
      }
      return matchAttributes;
    },
    //属性是否符合条件
    isAttributeMatchCondition(attribute, filterParameter) {
      if (attribute.parentAttribute && filterParameter.isOnlyFilterTopLevel)
        return true;
      let filterClassType = filterParameter.filterClassType;
      if (
        filterClassType &&
        filterClassType.indexOf(-1) < 0 &&
        filterClassType.indexOf(attribute.DataTypeFlag) < 0
      )
        return false;
      let filterGroupName = filterParameter.filterGroupName;
      if (
        filterGroupName &&
        filterGroupName.indexOf("-") < 0 &&
        filterGroupName.indexOf(attribute.GroupName) < 0
      )
        return false;
      let filterString = filterParameter.filterString;
      if (!filterString || filterString.length === 0) return true;
      filterString = filterString.toLowerCase();
      filterOperatorType = filterParameter.filterOperatorType;
      let nameLower = attribute.Name.toLowerCase();
      let displayName = attribute.DescFlexFieldDef
        ? attribute.DescFlexFieldDef.Name
        : attribute.DisplayName;
      let displayNameLower = displayName.toLowerCase();
      if (filterOperatorType === 0)
        return (
          nameLower.startsWith(filterString) ||
          displayNameLower.toLowerCase().startsWith(filterString)
        );
      if (filterOperatorType === 1)
        return (
          nameLower.includes(filterString) ||
          displayNameLower.includes(filterString)
        );
      if (filterOperatorType === 2)
        return (
          nameLower.endsWith(filterString) ||
          displayNameLower.endsWith(filterString)
        );
      if (filterOperatorType === 3)
        return nameLower === filterString || displayNameLower === filterString;
      return false;
    },
    //#endregion
    //#region 引用
    //获取实体属性表的引用
    getEntityAttributesTableRef(tab) {
      return this.getTabRef(tab, "EntityAttributesTableRef");
    },
    //获取实体属性表行名称的引用
    getEntityAttributesRowNameRef(attribute) {
      let tab = attribute.metedata.tab;
      return this.getTabRef(tab, attribute.attributeID + "_Name");
    },
    //获取实体属性表行OQL表达式的引用
    getEntityAttributesRowOQLExpressionRef(attribute) {
      let tab = attribute.metedata.tab;
      return this.getTabRef(tab, attribute.attributeID + "_OQLExpressionRef");
    },
    //获取实体属性表行公式表达式的引用
    getEntityAttributesRowFormulaExpressionRef(attribute) {
      let tab = attribute.metedata.tab;
      return this.getTabRef(
        tab,
        attribute.attributeID + "_FormulaExpressionRef"
      );
    },
    //获取Tab中的引用
    getTabRef(tab, refName) {
      let refID = tab.name + "_" + refName;
      let refs = this.$refs[refID];
      if (refs && refs.length && refs.length > 0) return refs[0];
      return refs;
    },
    //#endregion
    //#region 右键菜单
    //右键菜单
    onEntityAttributesTableCellMenu({
      type,
      row,
      rowIndex,
      $rowIndex,
      column,
      columnIndex,
      $columnIndex,
      $event,
    }) {
      //console.log('onEntityAttributesCellMenu', row.fullExpression)
      let tab = row.metedata.tab;
      let tableRef = this.getEntityAttributesTableRef(tab);
      var params = {
        $table: tableRef,
        row: row,
      };
      return tableRef.triggerCurrentRowEvent($event, params);
    },
    //右键菜单点击事件
    onEntityAttributesTableCellClick({
      menu,
      type,
      row,
      rowIndex,
      column,
      columnIndex,
      $event,
    }) {
      //console.log('onEntityAttributesCellClick', row.fullExpression)
      let tab = row.metedata.tab;
      let tableRef = this.getEntityAttributesTableRef(tab);
      if (menu.code === "autoExpandAll") {
        this.autoExpandEntityAttributesTable(tab, row);
      }
      if (menu.code === "collapseAll") {
        let rows = [];
        if (tableRef.isTreeExpandByRow(row)) rows.push(row);
        XEUtils.eachTree(
          row.childrenAttributes,
          (attribute) => {
            if (tableRef.isTreeExpandByRow(attribute)) rows.push(attribute);
          },
          { children: "childrenAttributes" }
        );
        tableRef.setTreeExpand(rows, false);
      }
      if (menu.code === "showCheckboxRecords") {
        //重置属性过滤
        this.resetAllAttributesShowStatus(tab);
        let selectedRows = tableRef.getCheckboxRecords(true);
        selectedRows.forEach((attribute) => {
          attribute.isShow = 1;
        });
        //设置实体属性表过滤
        this.setEntityAttributesTableFilter(tableRef, true);
        tableRef.updateData();
      }
      if (menu.code === "showAllRecords") {
        //重置属性过滤
        this.resetAllAttributesShowStatus(tab);
        //设置实体属性表过滤
        this.setEntityAttributesTableFilter(tableRef, false);
        tableRef.updateData();
      }
      //勾选当前显示行
      if (menu.code === "selectDisplayRecords") {
        tableRef.setCheckboxRow(tableRef.getTableData().visibleData, true);
      }
      //勾选下级节点
      if (menu.code === "selectLowerLevelRecords") {
        if (row.childrenAttributes && row.childrenAttributes.length > 0)
          tableRef.setCheckboxRow(row.childrenAttributes, true);
      }
      //勾选所有下级节点
      if (menu.code === "selectAllLowerLevelRecords") {
        if (row.childrenAttributes && row.childrenAttributes.length > 0) {
          let rows = [];
          XEUtils.eachTree(
            row.childrenAttributes,
            (attribute) => {
              rows.push(attribute);
            },
            { children: "childrenAttributes" }
          );
          tableRef.setCheckboxRow(rows, true);
        }
      }
      //取消勾选当前显示行
      if (menu.code === "unSelectDisplayRecords") {
        tableRef.setCheckboxRow(tableRef.getTableData().visibleData, false);
      }
      //取消勾选下级节点
      if (menu.code === "unSelectLowerLevelRecords") {
        if (row.childrenAttributes && row.childrenAttributes.length > 0)
          tableRef.setCheckboxRow(row.childrenAttributes, false);
      }
      //取消勾选所有下级节点
      if (menu.code === "unSelectAllLowerLevelRecords") {
        if (row.childrenAttributes && row.childrenAttributes.length > 0) {
          let rows = [];
          XEUtils.eachTree(
            row.childrenAttributes,
            (attribute) => {
              rows.push(attribute);
            },
            { children: "childrenAttributes" }
          );
          tableRef.setCheckboxRow(rows, false);
        }
      }
    },
    //右键菜单权限控制
    entityAttributesTableMenuVisibleMethod({
      type,
      options,
      columns,
      row,
      rowIndex,
      column,
      columnIndex,
    }) {
      //console.log('entityAttributesTableMenuVisibleMethod', row.fullExpression);
      let tab = row.metedata.tab;
      let tableRef = this.getEntityAttributesTableRef(tab);
      options.forEach((list) => {
        list.forEach((item) => {
          if (row) {
            if (item.code === "autoExpandAll") {
              item.disabled = !row.hasChildren;
            }
            if (item.code === "collapseAll") {
              item.disabled =
                !row.hasChildren && !tableRef.isTreeExpandByRow(row);
            }
            if (item.code === "showCheckboxRecords") {
              let selectedRows = tableRef.getCheckboxRecords(true);
              item.disabled = selectedRows.length <= 0;
            }
            //勾选当前显示行
            if (item.code === "selectDisplayRecords") {
              let visibleData = tableRef.getTableData().visibleData;
              item.disabled = !(visibleData && visibleData.length > 0);
            }
            //勾选下级节点
            if (item.code === "selectLowerLevelRecords") {
              item.disabled = !(
                row.childrenAttributes && row.childrenAttributes.length > 0
              );
            }
            //勾选所有下级节点
            if (item.code === "selectAllLowerLevelRecords") {
              item.disabled = !(
                row.childrenAttributes && row.childrenAttributes.length > 0
              );
            }
            //取消勾选当前显示行
            if (item.code === "unSelectDisplayRecords") {
              let visibleData = tableRef.getTableData().visibleData;
              item.disabled = !(visibleData && visibleData.length > 0);
            }
            //取消勾选下级节点
            if (item.code === "unSelectLowerLevelRecords") {
              item.disabled = !(
                row.childrenAttributes && row.childrenAttributes.length > 0
              );
            }
            //取消勾选所有下级节点
            if (item.code === "unSelectAllLowerLevelRecords") {
              item.disabled = !(
                row.childrenAttributes && row.childrenAttributes.length > 0
              );
            }
          } else {
            item.disabled = true;
          }
          if (item.children) {
            item.children.forEach((childItem) => {
              childItem.disabled = item.disabled;
            });
          }
        });
      });
      return true;
    },
    //勾选所有显示行
    onEntityAttributesTableCheckAll(tab, { checked, $event }) {
      //console.log("checked:", checked);
      let tableRef = this.getEntityAttributesTableRef(tab);
      tableRef.setCheckboxRow(tableRef.getTableData().visibleData, checked);
    },
    //当实体属性表选择发生变化
    onEntityAttributesTableCheckChange({
      checked,
      row,
      rowIndex,
      $rowIndex,
      column,
      columnIndex,
      $columnIndex,
      $event,
    }) {
      console.log("checked:", row.fullExpression, checked);
    },
    //#endregion
    //#region 弹出窗口
    //当属性OQL表达式点击时
    onAttributeOQLExpressionClick(attribute) {
      if (
        this.popover.oqlExpressionActiveAttribute == attribute &&
        this.$refs.oqlExpressionPopover.showPopper
      )
        return;
      let attrRef = this.getEntityAttributesRowOQLExpressionRef(attribute);
      this.popover.oqlExpressionShow = false;
      this.popover.oqlExpressionActiveAttribute = attribute;
      this.popover.oqlExpressionActiveReference = attrRef.$el;
      let $this = this;
      this.$nextTick(() => {
        $this.popover.oqlExpressionShow = true;
        $this.$nextTick(() => {
          $this.$refs.oqlExpressionPopover.doShow();
          if (attribute.oqlExpressions && attribute.oqlExpressions.length > 0) {
            attribute.oqlExpressions.forEach((oqlExpression, index) => {
              $this.$refs.oqlExpressionTable.toggleRowSelection(
                oqlExpression,
                true
              );
            });
          }
        });
      });
    },
    //当属性公式表达式点击时
    onAttributeFormulaExpressionClick(attribute) {
      if (
        this.popover.formulaExpressionActiveAttribute == attribute &&
        this.$refs.formulaExpressionPopover.showPopper
      )
        return;
      let attrRef = this.getEntityAttributesRowFormulaExpressionRef(attribute);
      this.popover.formulaExpressionShow = false;
      this.popover.formulaExpressionActiveAttribute = attribute;
      this.popover.formulaExpressionActiveReference = attrRef.$el;
      let $this = this;
      this.$nextTick(() => {
        $this.popover.formulaExpressionShow = true;
        $this.$nextTick(() => {
          $this.$refs.formulaExpressionPopover.doShow();
          if (
            attribute.formulaExpressions &&
            attribute.formulaExpressions.length > 0
          ) {
            attribute.formulaExpressions.forEach((formulaExpression, index) => {
              $this.$refs.formulaExpressionTable.toggleRowSelection(
                formulaExpression,
                true
              );
            });
          }
        });
      });
    },
    //获当前属性的OQL表达式
    getAttributeOQLExpressions() {
      if (!this.popover.oqlExpressionActiveAttribute) return [];
      if (!this.oqlExpressions) return [];
      let $this = this;
      let expressions = [];
      this.oqlExpressions.forEach((typeExpression, index) => {
        if (
          !typeExpression.filter ||
          typeExpression.filter.call(
            $this,
            this.popover.oqlExpressionActiveAttribute
          )
        ) {
          typeExpression.expressions.forEach((expression, index) => {
            if (
              !expression.filter ||
              expression.filter.call(
                $this,
                this.popover.oqlExpressionActiveAttribute
              )
            ) {
              if (
                expression.SQLType &&
                typeof expression.SQLType === "function"
              ) {
                expression.type = expression.SQLType.call(
                  $this,
                  this.popover.oqlExpressionActiveAttribute
                );
              } else {
                expression.type = expression.SQLType;
              }
              expressions.push(expression);
            }
          });
        }
      });
      return expressions;
    },
    //当OQL表达式弹出窗选择发生变化
    onOqlExpressionPopoverSelectChange(selection) {
      if (!this.$refs.oqlExpressionPopover) return;
      if (!this.$refs.oqlExpressionPopover.showPopper) return;
      if (!this.popover.oqlExpressionActiveAttribute) return;
      let attribute = this.popover.oqlExpressionActiveAttribute;
      attribute.oqlExpressions = selection;
      let tab = attribute.metedata.tab;
      let tableRef = this.getEntityAttributesTableRef(tab);
      let selected = selection && selection.length > 0;
      let attributeSelected = tableRef.isCheckedByCheckboxRow(attribute);
      if (selected) {
        if (!attributeSelected) tableRef.setCheckboxRow(attribute, true);
      } else {
        if (attributeSelected) tableRef.setCheckboxRow(attribute, false);
      }
    },
    //获当前属性的公式表达式
    getAttributeFormulaExpressions() {
      if (!this.popover.formulaExpressionActiveAttribute) return [];
      if (!this.formulaExpressions) return [];
      let $this = this;
      let expressions = [];
      this.formulaExpressions.forEach((typeExpression, index) => {
        if (
          !typeExpression.filter ||
          typeExpression.filter.call(
            $this,
            this.popover.formulaExpressionActiveAttribute
          )
        ) {
          typeExpression.expressions.forEach((expression, index) => {
            if (
              !expression.filter ||
              expression.filter.call(
                $this,
                this.popover.formulaExpressionActiveAttribute
              )
            )
              expressions.push(expression);
          });
        }
      });
      return expressions;
    },
    //当公式表达式弹出窗选择发生变化
    onFormulaExpressionPopoverSelectChange(selection) {
      if (!this.$refs.formulaExpressionPopover) return;
      if (!this.$refs.formulaExpressionPopover.showPopper) return;
      if (!this.popover.formulaExpressionActiveAttribute) return;
      let attribute = this.popover.formulaExpressionActiveAttribute;
      attribute.formulaExpressions = selection;
    },
    //#endregion
    //#region BPSV
    //打开代理测试文件
    onBPSVTestOpenFile(file, fileList) {
      if (!file) return;
      let $this = this;
      let reader = new FileReader();
      reader.readAsText(file.raw, "UTF-8");
      //读取文件完毕执行此函数
      reader.onload = async function (evt) {
        let jsonData;
        let bpsvFullName;
        try {
          jsonData = JSON.parse(evt.target.result);
          if (!jsonData.proxy || jsonData.proxy.length === 0) throw "error";
          let proxyFullName = jsonData.proxy.split(",")[0];
          if (!proxyFullName || proxyFullName.length === 0) throw "error";
          let arr = proxyFullName.split(".");
          arr[arr.length - 1] = arr[arr.length - 1].slice(0, -5);
          arr.splice(arr.length - 2, 1);
          bpsvFullName = arr.join(".");
        } catch (err) {
          $this.$notify.error({
            title: "错误",
            message: "解析文件失败",
            duration: 2000,
          });
        }
        if (!jsonData) return;
        let parameter = {
          classType: 7,
          queryString: bpsvFullName,
          focus: true,
        };
        $this.api().queryMetedata(parameter, function (res) {
          if (res.code === 0) {
            if (!res.data || res.data.length === 0) {
              $this.$notify.error({
                title: "错误",
                message: "未找到对应的服务",
                duration: 2000,
              });
            } else {
              $this.addBPSVTab(res.data[0].ID, false, function (tab) {
                if (tab.editor) {
                  $this
                    .$confirm("是否重新加载代理数据?", "提示", {
                      confirmButtonText: "加载",
                      cancelButtonText: "取消",
                      type: "info",
                    })
                    .then(() => {
                      tab.openBPSVFileName = file.name;
                      $this.setJsonEditorValue(
                        tab.editor,
                        JSON.stringify(jsonData.data)
                      );
                    })
                    .catch(() => {
                      console.log("取消");
                    });
                } else {
                  tab.openBPSVFileName = file.name;
                  $this.initBPSVEditor(tab, JSON.stringify(jsonData.data));
                }
              });
            }
          } else {
            $this.$notify.error({
              title: "错误",
              message: res && res.msg ? res.msg : "未知",
              duration: 2000,
            });
          }
        });
      };
    },
    //初始化Json编辑器
    initBPSVEditor(tab, proxyJsonString) {
      let $this = this;
      require(["vs/editor/editor.main"], function () {
        let cfg = $this.getEditorConfig("json");
        let requestEditorRefs =
          $this.$refs[tab.metedata.Key.ID + "_requestEditor"];
        if (
          requestEditorRefs &&
          requestEditorRefs.length &&
          requestEditorRefs.length > 0
        ) {
          let editor = monaco.editor.create(requestEditorRefs[0], cfg);
          tab.editor = editor;
          setTimeout(function () {
            if (proxyJsonString) {
              $this.setJsonEditorValue(editor, proxyJsonString);
            } else {
              $this.getProxyData(tab);
            }
          }, 100);
        }
        let resultEditorRefs =
          $this.$refs[tab.metedata.Key.ID + "_resultEditor"];
        if (
          resultEditorRefs &&
          resultEditorRefs.length &&
          resultEditorRefs.length > 0
        ) {
          let editor = monaco.editor.create(resultEditorRefs[0], cfg);
          tab.resulteditor = editor;
          // let keyID = tab.metedata.Key.ID;
          // $this.getCloneMetedata(keyID, NaN, function (metedata) {
          //     setTimeout(function () {
          //         editor.setValue(JSON.stringify(metedata));
          //         editor.trigger('anyString', 'editor.action.formatDocument');
          //         editor.setValue(editor.getValue());
          //     }, 100);
          // })
        }
      });
    },
    //给Json编码辑赋值
    setJsonEditorValue(editor, json) {
      editor.setValue(json);
      editor.trigger("anyString", "editor.action.formatDocument");
      editor.setValue(editor.getValue());
    },
    //加载代理数据
    getProxyData(tab) {
      let editor = tab.editor;
      let $this = this;
      tab.proxyAction.loadProxyDataLoading = true;
      this.api().getProxyData(tab.proxyParameter, function (res) {
        if (res.code === 0) {
          //console.log('proxyData', JSON.stringify(res.data))
          $this.setJsonEditorValue(editor, res.data.ProxyJsonString);
          tab.proxyAction.loadProxyDataLoading = false;
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //累计重载
    totalLoadProxyData(tab) {
      let editor = tab.editor;
      let oldJsonString = editor.getValue();
      let selectionRange = editor.getSelection();
      //勾选位置如果是特定字符,自动替换
      if (selectionRange) {
        let selectionText = editor.getModel().getValueInRange(selectionRange);
        if (selectionText === "null")
          editor.executeEdits(selectionText, [
            { range: selectionRange, text: "{}" },
          ]);
        if (selectionText === "[],")
          editor.executeEdits(selectionText, [
            { range: selectionRange, text: "[{}]," },
          ]);
      }
      let $this = this;
      tab.proxyAction.totalLoadProxyDataLoading = true;
      let currPosition = editor.getPosition();
      let parameter = {
        ...tab.proxyParameter,
        proxyJsonString: editor.getValue(),
      };
      this.api().totalGetProxyData(parameter, function (res) {
        if (res.code === 0) {
          console.log("proxyData", JSON.stringify(res.data));
          let data = res.data;
          editor.setValue(data.ProxyJsonString);
          editor.trigger("anyString", "editor.action.formatDocument");
          editor.setValue(editor.getValue());
          setTimeout(function () {
            editor.revealPositionNearTop(currPosition);
          }, 200);
        } else {
          editor.setValue(oldJsonString);
        }

        tab.proxyAction.totalLoadProxyDataLoading = false;
      });
    },
    //服务调试的命令
    handleBPSVDebugCommand(tab, command) {
      if (command == "clear") {
        this.handleTransactionDebugCommand(tab, command);
      }
      if (command === "global") {
        this.handleTransactionDebugCommand(tab, command);
      }
      if (command === "proxy") {
        this.handleTransactionDebugCommand(tab, command);
      }
      if (command === "interceptProxyData") {
        this.proxyDoDebug(tab);
      }
    },
    //事务调试的命令
    handleTransactionDebugCommand(tab, command) {
      if (!tab) return;
      let $this = this;
      if (command == "clear") {
        tab.transactionDebug.logData = [];
        return;
      }
      let isSetup = false;
      if (command === "global") {
        isSetup = !tab.transactionDebug.isSetupGlobal;
      }
      if (command === "proxy") {
        isSetup = !tab.transactionDebug.isSetupProxy;
      }
      this.closeTransactionDebug(tab);
      if (isSetup) {
        this.api().setupTransactionDebug(function (res) {
          if (res.code === 0) {
            let wsUrl =
              "ws://" +
              window.location.host +
              ":" +
              res.data.port +
              res.data.path;
            if (command === "proxy")
              wsUrl =
                wsUrl +
                "?proxyType=" +
                encodeURIComponent(
                  tab.proxyParameter.proxyFullName +
                    "," +
                    tab.proxyParameter.proxyAssemblyName
                );
            let webSocket = new WebSocket(wsUrl);
            webSocket.onopen = function (event) {
              console.log("transactionDebug connect successfully");
              tab.transactionDebug.webSocket = webSocket;
              if (command === "global") {
                tab.transactionDebug.isSetupGlobal = true;
              }
              if (command === "proxy") {
                tab.transactionDebug.isSetupProxy = true;
              }
            };
            webSocket.onmessage = function (event) {
              const message = event.data;
              //处理从服务器接收的消息
              console.log("Received message:", message);
              let data = JSON.parse(message);
              tab.transactionDebug.logData.unshift(data);
            };
            webSocket.onclose = function (event) {
              $this.closeTransactionDebug(tab);
              console.log("transactionDebug close successfully");
            };
          } else {
            $this.$notify.error({
              title: "错误",
              message: res && res.msg ? res.msg : "未知",
              position: "bottom-right",
              duration: 3000,
            });
          }
        });
      }
    },
    //关闭事务调试
    closeTransactionDebug(tab) {
      if (
        tab.transactionDebug.webSocket &&
        tab.transactionDebug.webSocket.readyState === 1
      )
        tab.transactionDebug.webSocket.close();
      tab.transactionDebug.webSocket = NaN;
      tab.transactionDebug.isSetupGlobal = false;
      tab.transactionDebug.isSetupProxy = false;
    },
    //其它操作菜单命令
    handleBPSVTestOtherCommand(tab, command) {
      if (command == "copyRequestData") {
        this.copyRequestData(tab);
      }
      if (command == "copyWSSRequestData") {
        this.copyWSSRequestData(tab);
      }
      if (command == "copyWSSRequestDataWithContext") {
        this.copyWSSRequestData(tab, true);
      }
      if (command === "copyResultData") {
        this.copyResultData(tab);
      }
      if (command === "saveWSSRequestDataFile") {
        this.saveWSSRequestDataFile(tab);
      }
      if (command === "saveWSSRequestDataFileWithContext") {
        this.saveWSSRequestDataFile(tab, true);
      }
      if (command === "linkToWSS") {
        this.linkToWSS();
      }
      if (command === "createRunableBPSVSQL") {
        this.createRunableBPSVSQL(tab);
      }
    },
    //发送代理请求
    sendProxyReqeust(tab) {
      let editor = tab.editor;
      let resulteditor = tab.resulteditor;
      let $this = this;
      tab.proxyAction.proxyDoLoading = true;
      let parameter = {
        ...tab.proxyParameter,
        proxyJsonString: editor.getValue(),
      };
      this.api().proxyDo(parameter, function (res) {
        if (res.code === 0) {
          let returnJsonString = res.data;
          console.log("proxyData", returnJsonString);
          resulteditor.setValue(returnJsonString);
          resulteditor.trigger("anyString", "editor.action.formatDocument");
          resulteditor.setValue(resulteditor.getValue());
          tab.currentBPSVTabIndex = "bpsvTabMainTestResultTab";
        } else {
          resulteditor.setValue("");
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: res.code === 1 ? 1000 : 5000,
          });
        }
        tab.proxyAction.proxyDoLoading = false;
      });
    },
    //拦截数据
    proxyDoDebug(tab) {
      let $this = this;
      let isSetup = !tab.proxyDoDebug.proxyDoDebugLoading;
      if (isSetup) {
        this.api().setupProxyDoDebug(function (res) {
          if (res.code === 0) {
            let wsUrl =
              "ws://" +
              window.location.host +
              ":" +
              res.data.port +
              res.data.path;
            wsUrl =
              wsUrl +
              "?proxyType=" +
              encodeURIComponent(
                tab.proxyParameter.proxyFullName +
                  "," +
                  tab.proxyParameter.proxyAssemblyName
              );
            let webSocket = new WebSocket(wsUrl);
            webSocket.onopen = function (event) {
              console.log("proxyDoDebug connect successfully");
              tab.proxyDoDebug.webSocket = webSocket;
              tab.proxyDoDebug.proxyDoDebugLoading = true;
            };
            webSocket.onmessage = function (event) {
              const message = event.data;
              //处理从服务器接收的消息
              console.log("Received message:", message);
              let data = JSON.parse(message);
              if (!data) return;
              if (
                data.proxyFullName !== tab.proxyParameter.proxyFullName ||
                data.proxyAssemblyName !== tab.proxyParameter.proxyAssemblyName
              )
                return;
              if (data.requestData) {
                $this
                  .$confirm("拦截到请求数据,是否加载?", "提示", {
                    confirmButtonText: "加载",
                    cancelButtonText: "忽略",
                    type: "info",
                  })
                  .then(() => {
                    let editor = tab.editor;
                    editor.setValue(data.requestData);
                    editor.trigger("anyString", "editor.action.formatDocument");
                    editor.setValue(editor.getValue());
                    tab.currentBPSVTabIndex = "bpsvTabMainTestRequestTab";
                  })
                  .catch(() => {
                    console.log("取消");
                  });
              }
              if (data.resultData) {
                $this
                  .$confirm("拦截到返回数据,是否加载?", "提示", {
                    confirmButtonText: "加载",
                    cancelButtonText: "取消",
                    type: "info",
                  })
                  .then(() => {
                    let editor = tab.resulteditor;
                    editor.setValue(data.resultData);
                    editor.trigger("anyString", "editor.action.formatDocument");
                    editor.setValue(editor.getValue());
                    tab.currentBPSVTabIndex = "bpsvTabMainTestResultTab";
                  })
                  .catch(() => {
                    console.log("取消");
                  });
              }
            };
            webSocket.onclose = function (event) {
              $this.closeProxyDoDebug(tab);
              console.log("proxyDoDebug close successfully");
            };
          } else {
            $this.$notify.error({
              title: "错误",
              message: res && res.msg ? res.msg : "未知",
              position: "bottom-right",
              duration: 3000,
            });
          }
        });
      } else {
        $this.closeProxyDoDebug(tab);
      }
    },
    //关闭拦截数据
    closeProxyDoDebug(tab) {
      if (
        tab.proxyDoDebug.webSocket &&
        tab.proxyDoDebug.webSocket.readyState === 1
      )
        tab.proxyDoDebug.webSocket.close();
      tab.proxyDoDebug.webSocket = NaN;
      tab.proxyDoDebug.proxyDoDebugLoading = false;
    },
    //复制请求数据
    copyRequestData(tab) {
      let editor = tab.editor;
      this.copyToClipboard(editor.getValue());
    },
    //复制WSS请求数据
    copyWSSRequestData(tab, withContext) {
      this.copyToClipboard(this.createWSSRequestData(tab, withContext));
    },
    //保存WSS文件
    saveWSSRequestDataFile(tab, withContext) {
      let blob = new Blob([this.createWSSRequestData(tab, withContext)], {
        type: "text/plain;charset=utf-8",
      });
      let fileName =
        tab.openBPSVFileName && tab.openBPSVFileName.length > 0
          ? tab.openBPSVFileName
          : tab.title + ".json";
      saveAs(blob, fileName);
    },
    //连接WSS
    linkToWSS() {
      window.open("https://gitee.com/mutongtech/wss", "_blank");
    },
    //生成BPSV调度脚本
    createRunableBPSVSQL(tab) {
      let metedata = tab.metedata;
      let sql = ""
        .concat("--" + metedata.DisplayName + "\r\n")
        .concat("DELETE FROM UBF_JOB_NoParaRunableBPSVList\r\n")
        .concat("WHERE FullName = '" + metedata.Key.FullName + "'\r\n")
        .concat(
          "INSERT INTO UBF_JOB_NoParaRunableBPSVList (ID, FullName, Memo)\r\n"
        )
        .concat("SELECT a.ID,a.FullName,at.DisplayName\r\n")
        .concat(
          "FROM UBF_MD_Class a LEFT JOIN UBF_MD_Class_Trl at ON at.Local_ID = a.Local_ID AND SysMLFlag = 'zh-CN'\r\n"
        )
        .concat("WHERE a.FullName = '" + metedata.Key.FullName + "'");
      this.copyToClipboard(sql);
    },
    //创建WSS请求数据
    createWSSRequestData(tab, withContext) {
      let editor = tab.editor;
      let data = {};
      if (withContext) data.context = this.createWSSContext();
      data.proxy = tab.proxyParameter.proxyFullName
        .concat(",")
        .concat(tab.proxyParameter.proxyAssemblyName);
      let jsonString = editor.getValue();
      if (!jsonString || jsonString.length === 0) {
        data.data = {};
      } else {
        try {
          data.data = JSON.parse(jsonString);
        } catch (err) {
          console.log("createWSSRequestData err:", err);
          data.data = jsonString;
        }
      }
      return JSON.stringify(data, null, "\t");
    },
    //创建WSS的上下文
    createWSSContext() {
      let contextData = this.index.contextData;
      if (!contextData) return null;
      return {
        enterpriseID: contextData.EnterpriseID,
        orgCode: contextData.OrgCode,
        userCode: contextData.UserCode,
        password: "",
        culture: contextData.Culture,
        supportCultureNameList: contextData.Support_CultureName_List,
      };
    },
    //复制返回数据
    copyResultData(tab) {
      let editor = tab.resulteditor;
      this.copyToClipboard(editor.getValue());
    },
    //获取事务类型数组
    getTransactionTypeOptions() {
      let options = [];
      this.enums.transactionTypeOptions.forEach((option, index) => {
        options.push({
          label: option.name,
          key: option.value,
          value: option.value,
        });
      });
      return options;
    },
    //获取类型数组
    getTransactionDebugLogTypeOptions() {
      return [
        { label: "BPSV", key: "BPSV", value: "BPSV" },
        { label: "自定义", key: "自定义", value: "自定义" },
      ];
    },
    //通用过滤
    commonFilterHandler({ value, row, column }) {
      const property = column["property"];
      return row[column.property] === value;
    },
    //日志名称过滤
    filterLogNameMethod({ option, row }) {
      let name = row.bpsvMetedata ? row.bpsvMetedata.name : "";
      let filterString = option.data ? option.data.toLowerCase() : "";
      return name.toLowerCase().includes(filterString);
    },
    //日志显示名称过滤
    filterLogDisplayNameMethod({ option, row }) {
      let displayName = row.bpsvMetedata ? row.bpsvMetedata.displayName : "";
      let filterString = option.data ? option.data.toLowerCase() : "";
      return displayName.toLowerCase().includes(filterString);
    },
    //事务日志排序方法
    transactionDebugLogSortMethod({ data, sortList }) {
      const sortItem = sortList[0];
      const { property, order } = sortItem;
      return XEUtils.orderBy(data, [[property, order]]);
    },
    //右键菜单点击事件
    onTransactionDebugLogTableCellClick(
      tab,
      { menu, type, row, rowIndex, column, columnIndex, $event }
    ) {
      //console.log('onTransactionDebugLogTableCellClick')
      let tableRef = this.getTransactionDebugLogTableRef(tab);
      if (menu.code === "clearLogData") {
        tab.transactionDebug.logData = [];
      }
      if (menu.code === "clearFilter") {
        tableRef.clearFilter();
      }
      if (menu.code === "clearSort") {
        tableRef.clearSort();
      }
    },
    //获取事务日志表的引用
    getTransactionDebugLogTableRef(tab) {
      return this.getTabRef(tab, "TransactionDebugLogTableRef");
    },
    //#endregion
    //#region CustomProxy
    //新增CustomProxyQueryTab
    addCustomProxyQueryTab() {
      let tabType = "customProxyQuery";
      let keyID = tabType;
      if (this.currentTabIndex === keyID) return;
      let tab = this.tabs.find((item) => item.name && item.name == keyID);
      if (tab) {
        tab.preTabIndex = this.currentTabIndex;
        this.currentTabIndex = tab.name;
        return;
      }
      let $this = this;
      tab = {
        name: keyID,
        type: tabType,
        title: "自定义代理列表",
        preTabIndex: $this.currentTabIndex,
        queryForm: { queryString: "", loading: false },
        queryResult: [],
      };
      $this.tabs.push(tab);
      $this.currentTabIndex = keyID;
    },
    //#endregion
    //#region OQL
    //初始化OQL编辑器
    initOQLEditor(tab, oql) {
      let $this = this;
      require(["vs/editor/editor.main"], function () {
        let oqlEditorRefs = $this.$refs[tab.name + "_OQLEditor"];
        if (oqlEditorRefs && oqlEditorRefs.length && oqlEditorRefs.length > 0) {
          let cfg = $this.getEditorConfig("sql", oql);
          let editor = monaco.editor.create(oqlEditorRefs[0], cfg);
          tab.OQLEditor = editor;
          editor.isOQL = true;
        }
        let sqlEditorRefs = $this.$refs[tab.name + "_SQLEditor"];
        if (sqlEditorRefs && sqlEditorRefs.length && sqlEditorRefs.length > 0) {
          let cfg = $this.getEditorConfig("sql");
          let editor = monaco.editor.create(sqlEditorRefs[0], cfg);
          tab.SQLEditor = editor;
        }
      });
    },
    //通过实体Tab生成OQL
    createOQLFromEntityTab(tab, oqlParameter, oldOql) {
      if (!tab) return;
      let $this = this;
      let metedata = tab.metedata;
      let tableRef = this.getEntityAttributesTableRef(tab);
      if (!tableRef) return;
      let selectedRows = tableRef.getCheckboxRecords(true);
      //设置行号
      let rowIndex = 0;
      XEUtils.eachTree(
        metedata.Attributes,
        (attribute) => {
          attribute.rowIndex = ++rowIndex;
        },
        { children: "childrenAttributes" }
      );
      //按行号排列
      let sortSelectedRows = selectedRows.concat();
      sortSelectedRows.sort((a, b) => {
        return a.rowIndex > b.rowIndex ? 1 : -1;
      });
      if (oqlParameter && oqlParameter.sortFieldByRowIndex) {
        selectedRows = sortSelectedRows.concat();
      }
      //关联
      let expandEntityTable = oqlParameter && oqlParameter.expandEntityTable;
      let associationAttributes = [];
      let treeElements = [];
      let allElements = [];
      if (expandEntityTable) {
        //找出所有关联的属性
        sortSelectedRows.forEach((attribute, index) => {
          if (attribute.parentAttribute)
            $this.addAttributeInAssociationAttributes(
              associationAttributes,
              attribute.parentAttribute
            );
        });
        //构建树
        let treeElement;
        associationAttributes.forEach((attribute, index) => {
          let parentAttribute =
            this.getAttributeEntityParentAttribute(attribute);
          if (!parentAttribute) {
            treeElement = {
              attribute: attribute,
              tableAliasName: attribute.fullExpression.replace(/\./g, "_"),
              childElements: [],
            };
            treeElements.push(treeElement);
            allElements.push(treeElement);
          } else {
            this.createAttributeTreeElement(
              allElements,
              treeElement,
              attribute
            );
          }
        });
      }
      let oqls = ["select "];
      let isFirst = true;
      let displayNames = [];
      if (selectedRows && selectedRows.length > 0) {
        selectedRows.forEach((attribute, index) => {
          if (attribute.DataTypeFlag !== 2 && attribute.DataTypeFlag !== 4) {
            let displayName =
              oqlParameter && oqlParameter.useEngcolumnAliasName
                ? attribute.fullExpression
                : attribute.fullExpressionDisplayName;
            displayName = displayName.replace(/[\.\-(－＿（]/g, "_");
            displayName = $this.removeSpecialChar(displayName);
            if (!isFirst) {
              oqls.push(",");
            }
            oqls.push("\r\n", "  ");
            let i = 0;
            let tempDisplayName = displayName;
            while (true) {
              if (displayNames.indexOf(displayName) < 0) break;
              i++;
              displayName = tempDisplayName.concat(i);
            }
            displayNames.push(displayName);
            isFirst = false;
            let sqlFieldName;
            let parentElement;
            if (expandEntityTable) {
              parentElement = this.getAttributeParentTreeElement(
                allElements,
                attribute
              );
              if (parentElement) {
                sqlFieldName =
                  parentElement.tableAliasName +
                  attribute.fullExpression.slice(
                    parentElement.attribute.fullExpression.length
                  );
              } else {
                sqlFieldName = attribute.fullExpression;
              }
            } else {
              sqlFieldName = attribute.fullExpression;
            }
            oqls.push(sqlFieldName, " as ", displayName);
            if (
              attribute.oqlExpressions &&
              attribute.oqlExpressions.length > 0
            ) {
              attribute.oqlExpressions.forEach((oqlExpression, index) => {
                oqls.push(",", "\r\n", "  ");
                let expressionDisplayName = displayName.concat(
                  "_",
                  $this.removeSpecialChar(
                    oqlParameter && oqlParameter.useEngcolumnAliasName
                      ? oqlExpression.code
                      : oqlExpression.name
                  )
                );
                let tempExpressionDisplayName = expressionDisplayName;
                let i = 0;
                while (true) {
                  if (displayNames.indexOf(expressionDisplayName) < 0) break;
                  i++;
                  expressionDisplayName = tempExpressionDisplayName.concat(i);
                }
                displayNames.push(expressionDisplayName);
                let expressionSQLFieldName =
                  oqlExpression.expression(attribute);
                if (expandEntityTable && parentElement) {
                  expressionSQLFieldName = expressionSQLFieldName.replace(
                    new RegExp(
                      attribute.fullExpression.slice(
                        0,
                        parentElement.attribute.fullExpression.length
                      ),
                      "g"
                    ),
                    parentElement.tableAliasName
                  );
                }
                oqls.push(
                  expressionSQLFieldName,
                  " as ",
                  expressionDisplayName
                );
              });
            }
          }
        });
      } else {
        oqls.push("\r\n", "  ", "* ");
      }
      oqls.push("\r\n", "from ");
      //主表
      oqls.push(
        "\r\n",
        "  ",
        this.getEntityOQLFullName(metedata.Key.FullName),
        " ",
        metedata.Key.Name
      );
      //扩展子表
      if (expandEntityTable) {
        treeElements.forEach((treeElement, index) => {
          this.addJoinTableInOql(oqls, treeElement, metedata.Key.Name);
        });
      }
      //where条件
      if (oqlParameter) {
        let reserveFilter;
        //重构OQL保留过滤条件
        if (oldOql && oqlParameter.reserveFilterWhenReBuildOQL) {
          let index = oldOql.toLowerCase().indexOf("where");
          if (index > 0) {
            reserveFilter = oldOql.slice(index);
            if (reserveFilter) oqls.push("\r\n", reserveFilter);
          }
        }
        // 主键作为过滤条件
        if (!reserveFilter && oqlParameter.useBusinessKeyForParams) {
          oqls.push("\r\n", "where ");
          if (metedata.BKAttributes && metedata.BKAttributes.length > 0) {
            metedata.BKAttributes.forEach((bkAttribute, index) => {
              oqls.push(
                "\r\n",
                "  ",
                index > 0 ? " and " : "",
                metedata.Key.Name,
                ".",
                bkAttribute,
                " = ",
                "@",
                bkAttribute.replace(/\./g, "_")
              );
            });
          } else {
            oqls.push("\r\n", "  ", metedata.Key.Name, ".ID = @ID");
          }
        }
      }

      return oqls.join("");
    },
    //执行OQL
    getOQLQueryResult(tab, pageIndex, pageSize) {
      if (!tab.runOQLResult.pageParamter)
        tab.runOQLResult.pageParamter = tab.defaultPageParamter;
      if (typeof pageIndex !== "undefined")
        tab.runOQLResult.pageParamter.pageIndex = pageIndex;
      if (pageSize) tab.runOQLResult.pageParamter.pageSize = pageSize;
      let oqlEditor = tab.OQLEditor;
      let $this = this;
      tab.oqlAction.runOqlLoading = true;
      let pageParamter = tab.runOQLResult.pageParamter;
      this.api().runOQL(oqlEditor.getValue(), pageParamter, function (res) {
        if (res.code === 0) {
          //console.log('queryResult', res.data)
          tab.currentOQLTabIndex = "oqlTabMainResultTab";
          $this.$set(tab, "runOQLResult", JSON.parse(res.data));
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: 6000,
          });
        }

        tab.oqlAction.runOqlLoading = false;
      });
    },
    //查询结果页大小变化
    handleOQLResultTableSizeChange(pageSize) {
      let $this = this;
      let tab = $this.tabs.find((item) => item.name == $this.currentTabIndex);
      if (!tab) return;
      this.getOQLQueryResult(tab, 0, pageSize);
    },
    //查询结果当前页变化
    handleOQLResultTableCurrentChange(pageIndex) {
      let $this = this;
      let tab = $this.tabs.find((item) => item.name == $this.currentTabIndex);
      if (!tab) return;
      this.getOQLQueryResult(tab, pageIndex - 1);
    },
    //获取执行OQL结果的所有列
    getRunOQLResultColumns(tab) {
      if (!tab || !tab.runOQLResult || !tab.runOQLResult.queryData) return [];
      let queryDatas = tab.runOQLResult.queryData;
      if (queryDatas.length === 0) return [];
      let queryData = queryDatas[0];
      let columns = [];
      for (const prop in queryData) {
        if (prop === "__Qry_RowNumber") continue;
        columns.push(prop);
      }
      return columns;
    },
    //获取执行OQL结果的格式
    runOQLResultFormatter(row, column, cellValue) {
      if (typeof cellValue === "boolean") return cellValue ? "true" : "false";
      return cellValue;
    },
    //表头部重新渲染
    renderRunOQLResultHeader(h, { column, $index }) {
      let span = document.createElement("span");
      span.innerText = column.label;
      document.body.appendChild(span);
      column.minWidth = span.getBoundingClientRect().width + 40;
      document.body.removeChild(span);
      return h("span", column.label);
    },
    //依据来源重构OQL
    createOQLBySrcTab(tab) {
      let oqlEditor = tab.OQLEditor;
      let oql;
      if (tab.srcTab.type == "entity")
        oql = this.createOQLFromEntityTab(
          tab.srcTab,
          tab.oqlParameter,
          oqlEditor.getValue()
        );
      if (tab.srcTab.type == "enum")
        oql = this.createOQLFromEnumTab(tab.srcTab);
      if (!oql) return;
      oqlEditor.setValue(oql);
      this.formatEditorValue(oqlEditor);
      tab.currentOQLTabIndex = "oqlTabMainOQLTab";
    },
    //获取SQL
    getSQLByOQL(tab) {
      let oqlEditor = tab.OQLEditor;
      let sqlEditor = tab.SQLEditor;
      let $this = this;
      tab.oqlAction.convertOqlToSqlLoading = true;
      this.api().convertOqlToSql(oqlEditor.getValue(), function (res) {
        if (res.code === 0) {
          let sql = res.data;
          console.log("sql", sql);
          if (
            tab.srcTab &&
            tab.srcTab.type == "entity" &&
            tab.oqlParameter &&
            tab.oqlParameter.createTempTableWhenCreateSQL
          ) {
            let tempTableSQL = $this.createTempTableSQL(
              tab.srcTab,
              tab.oqlParameter
            );
            sql = tempTableSQL + "\r\n" + sql;
          }
          sqlEditor.setValue(sql);
          $this.formatEditorValue(sqlEditor);
          tab.currentOQLTabIndex = "oqlTabMainSQLTab";
          $this.$message({
            message: "转换SQL成功",
            type: "success",
            duration: 1000,
          });
        } else {
          //sqlEditor.setValue('');
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: 6000,
          });
        }
        tab.oqlAction.convertOqlToSqlLoading = false;
      });
    },
    //生成创建临时表SQL
    createTempTableSQL(tab, oqlParameter) {
      if (!tab || tab.type !== "entity") return "";
      let $this = this;
      let metedata = tab.metedata;
      let tableRef = this.getEntityAttributesTableRef(tab);
      if (!tableRef) return;
      let selectedRows = tableRef.getCheckboxRecords(true);
      if (!selectedRows || selectedRows.length === 0) return "";
      if (oqlParameter && oqlParameter.sortFieldByRowIndex) {
        let rowIndex = 0;
        XEUtils.eachTree(
          metedata.Attributes,
          (attribute) => {
            attribute.rowIndex = ++rowIndex;
          },
          { children: "childrenAttributes" }
        );
        selectedRows.sort((a, b) => {
          return a.rowIndex > b.rowIndex ? 1 : -1;
        });
      }
      let oqls = [
        "IF OBJECT_ID('tempdb..#" + metedata.Name + "TempTable') IS NOT NULL",
      ];
      oqls.push("\r\n", "  ", "DROP TABLE #" + metedata.Name + "TempTable;");
      oqls.push("\r\n", "CREATE TABLE #" + metedata.Name + "TempTable");
      oqls.push("\r\n", "(");
      let isFirst = true;
      let displayNames = [];
      selectedRows.forEach((attribute, index) => {
        if (attribute.DataTypeFlag !== 2 && attribute.DataTypeFlag !== 4) {
          let displayName =
            oqlParameter && oqlParameter.useEngcolumnAliasName
              ? attribute.fullExpression
              : attribute.fullExpressionDisplayName;
          displayName = displayName.replace(/[\.\-(－＿（]/g, "_");
          displayName = $this.removeSpecialChar(displayName);
          if (!isFirst) oqls.push(",");
          isFirst = false;
          oqls.push("\r\n", "  ");
          let i = 0;
          let tempDisplayName = displayName;
          while (true) {
            if (displayNames.indexOf(displayName) < 0) break;
            i++;
            displayName = tempDisplayName.concat(i);
          }
          displayNames.push(displayName);
          oqls.push(
            "[",
            displayName,
            "]",
            " ",
            $this.getAttributSQLType(attribute)
          );
          if (attribute.oqlExpressions && attribute.oqlExpressions.length > 0) {
            attribute.oqlExpressions.forEach((oqlExpression, index) => {
              oqls.push(",", "\r\n", "  ");
              let expressionDisplayName = displayName.concat(
                "_",
                this.removeSpecialChar(
                  oqlParameter && oqlParameter.useEngcolumnAliasName
                    ? oqlExpression.code
                    : oqlExpression.name
                )
              );
              let tempExpressionDisplayName = expressionDisplayName;
              let i = 0;
              while (true) {
                if (displayNames.indexOf(expressionDisplayName) < 0) break;
                i++;
                expressionDisplayName = tempExpressionDisplayName.concat(i);
              }
              displayNames.push(expressionDisplayName);
              oqls.push(
                "[",
                expressionDisplayName,
                "]",
                " ",
                typeof oqlExpression.SQLType === "function"
                  ? oqlExpression.SQLType.call($this, attribute)
                  : oqlExpression.SQLType
              );
            });
          }
        }
      });
      oqls.push("\r\n", ")");
      oqls.push("\r\n" + "INSERT INTO #" + metedata.Name + "TempTable");
      return oqls.join("");
    },
    //获取属性的SQL类型
    getAttributSQLType(attribute) {
      //基础类型
      if (attribute.DataTypeFlag === 0) {
        if (attribute.DataTypeKey.FullName === "System.String")
          return (
            "NVARCHAR(" +
            (attribute.Length > 0 ? attribute.Length : "MAX") +
            ")"
          );
        if (attribute.DataTypeKey.FullName === "System.Int32") return "INT";
        if (attribute.DataTypeKey.FullName === "System.Int64") return "BIGINT";
        if (
          attribute.DataTypeKey.FullName === "System.Date" ||
          attribute.DataTypeKey.FullName === "System.DateTime"
        )
          return "DATETIME";
        if (attribute.DataTypeKey.FullName === "System.Decimal")
          return "DECIMAL(" + attribute.Precision + "," + attribute.Scale + ")";
        if (attribute.DataTypeKey.FullName === "System.Boolean") return "BIT";
        if (attribute.DataTypeKey.FullName === "System.Guid")
          return "NVARCHAR(50)";
        if (attribute.DataTypeKey.FullName === "System.Byte[]")
          return "VARBINARY(MAX)";
      }
      //实体
      if (attribute.DataTypeFlag === 1) return "BIGINT";
      //枚举
      if (attribute.DataTypeFlag === 3) return "INT";
      return "";
    },
    //添加实体或集合属性进关联属性集合
    addAttributeInAssociationAttributes(associationAttributes, attribute) {
      let parentAttribute = attribute.parentAttribute;
      if (parentAttribute)
        this.addAttributeInAssociationAttributes(
          associationAttributes,
          parentAttribute
        );
      if (attribute.DataTypeFlag === 1 || attribute.DataTypeFlag === 4) {
        if (associationAttributes.indexOf(attribute) < 0)
          associationAttributes.push(attribute);
      }
    },
    //创建属性的树节点
    createAttributeTreeElement(elements, element, attribute) {
      let isChild = false;
      for (let i = 0; i < element.childElements.length; i++) {
        if (
          attribute.fullExpression.startsWith(
            element.childElements[i].attribute.fullExpression
          )
        ) {
          this.createAttributeTreeElement(
            elements,
            element.childElements[i],
            attribute
          );
          isChild = true;
          break;
        }
      }
      if (!isChild) {
        let childElement = {
          attribute: attribute,
          tableAliasName: attribute.fullExpression.replace(/\./g, "_"),
          childElements: [],
        };
        elements.push(childElement);
        element.childElements.push(childElement);
      }
    },
    //添加关联表到Oql中
    addJoinTableInOql(oqls, treeElement, parentTableAliasName, isNullable) {
      if (isNullable === undefined)
        isNullable = treeElement.attribute.IsNullable;
      oqls.push(
        "\r\n",
        "  ",
        isNullable || treeElement.attribute.IsNullable
          ? "left join "
          : "inner join ",
        this.getEntityOQLFullName(treeElement.attribute.DataTypeKey.FullName),
        " ",
        treeElement.tableAliasName
      );
      let association = treeElement.attribute.association;
      if (association) {
        if (association.Kind === 0) {
          let fieldName = treeElement.attribute.Name;
          let parentAttribute = treeElement.attribute.parentAttribute;
          while (parentAttribute) {
            if (parentAttribute.DataTypeFlag === 2) {
              fieldName = parentAttribute.Name + "." + fieldName;
              parentAttribute = parentAttribute.parentAttribute;
            } else {
              break;
            }
          }
          oqls.push(
            " on ",
            treeElement.tableAliasName,
            ".ID",
            " = ",
            parentTableAliasName,
            ".",
            fieldName
          );
        } else {
          oqls.push(
            " on ",
            treeElement.tableAliasName,
            ".",
            association.ChildMemberKey.Name,
            " = ",
            parentTableAliasName,
            ".ID"
          );
        }
      } else {
        let fieldName = treeElement.attribute.Name;
        let parentAttribute = treeElement.attribute.parentAttribute;
        while (parentAttribute) {
          if (parentAttribute.DataTypeFlag === 2) {
            fieldName = parentAttribute.Name + "." + fieldName;
            parentAttribute = parentAttribute.parentAttribute;
          } else {
            break;
          }
        }
        oqls.push(
          " on ",
          treeElement.tableAliasName,
          ".ID",
          " = ",
          parentTableAliasName,
          ".",
          treeElement.attribute.Name
        );
      }
      if (treeElement.childElements && treeElement.childElements.length > 0) {
        treeElement.childElements.forEach((childElement, index) => {
          this.addJoinTableInOql(
            oqls,
            childElement,
            treeElement.tableAliasName,
            isNullable || treeElement.attribute.IsNullable
          );
        });
      }
    },
    //获取属性的父级节点
    getAttributeParentTreeElement(allElements, attribute) {
      let parentAttribute = this.getAttributeEntityParentAttribute(attribute);
      if (!parentAttribute) return null;
      while (parentAttribute) {
        let parentElement = allElements.find(
          (item) => item.attribute === parentAttribute
        );
        if (parentElement) return parentElement;
        parentAttribute = parentAttribute.parentAttribute;
      }
    },
    //找到属性的实体父属性
    getAttributeEntityParentAttribute(attribute) {
      if (!attribute.parentAttribute) return NaN;
      let parentAttribute = attribute.parentAttribute;
      if (parentAttribute.DataTypeFlag !== 2) return parentAttribute;
      while (true) {
        return this.getAttributeEntityParentAttribute(parentAttribute);
      }
    },
    //OQL上下文写入
    handleContextWriteOqlCommand(tab, command) {
      let editor = tab.OQLEditor;
      let selectionRange = editor.getSelection();
      if (selectionRange) {
        let contextString = "#Context." + command + "#";
        if (
          command == "EnterpriseID" ||
          command == "EnterpriseName" ||
          command == "OrgCode" ||
          command == "OrgName" ||
          command == "UserCode" ||
          command == "UserName" ||
          command == "CultureName" ||
          command == "DateTime"
        ) {
          contextString = "'" + contextString + "'";
        }
        let selectionText = editor.getModel().getValueInRange(selectionRange);
        editor.executeEdits(selectionText, [
          { range: selectionRange, text: contextString },
        ]);
      }
    },
    //#endregion
    //#region Enum
    //刷新全部枚举
    refreshAllEnum(tab) {
      let $this = this;
      this.$set(tab, "isRefreshAllEnumLoading", true);
      this.api().refreshAllEnum(function (res) {
        if (res.code === 0) {
          $this.$message({
            message: "刷新全部枚举成功",
            type: "success",
            duration: 1000,
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: 5000,
          });
        }
        $this.$set(tab, "isRefreshAllEnumLoading", false);
      });
    },
    //刷新单个枚举
    refreshSingleEnum(tab) {
      let $this = this;
      this.$set(tab, "isRefreshSingleEnumLoading", true);
      let parameter = {
        enumFullName: tab.metedata.Key.FullName,
      };
      this.api().refreshSingleEnum(parameter, function (res) {
        if (res.code === 0) {
          $this.$message({
            message: "刷新当前枚举成功",
            type: "success",
            duration: 1000,
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            position: "bottom-right",
            duration: 5000,
          });
        }
        $this.$set(tab, "isRefreshSingleEnumLoading", false);
      });
    },
    //#endregion
    //#region RefQuery
    //新增RefQueryTab
    addRefQueryTab(srcTab, queryString, likeChecked) {
      let tabType = "refQuery";
      let keyID = srcTab
        ? tabType + "-" + srcTab.name
        : tabType + "-" + Math.uuid();
      if (this.currentTabIndex === keyID) return;
      let tab = this.tabs.find((item) => item.name && item.name == keyID);
      if (tab) {
        tab.preTabIndex = this.currentTabIndex;
        this.currentTabIndex = tab.name;
        return;
      }
      let $this = this;
      tab = {
        name: keyID,
        type: tabType,
        title: "参照查询",
        srcTab: srcTab,
        preTabIndex: $this.currentTabIndex,
        queryForm: {
          queryString: queryString,
          likeChecked: typeof likeChecked !== "undefined" ? likeChecked : true,
          loading: false,
        },
        queryResult: [],
      };
      $this.tabs.push(tab);
      $this.currentTabIndex = keyID;
      if (queryString) {
        $this.$nextTick(() => {
          $this.queryRef(tab);
        });
      }
    },
    //查询参照
    queryRef(tab) {
      let parameter = {
        queryString: tab.queryForm.queryString,
        like: tab.queryForm.likeChecked,
      };
      tab.queryForm.loading = true;
      let $this = this;
      this.api().queryRef(parameter, function (res) {
        console.log("查询结果", res);
        tab.queryForm.loading = false;
        if (res.code === 0) {
          tab.queryResult = res.data.map((item, index) => {
            item.activeNames = [];
            return item;
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //查询结果行双击事件
    onRefQueryResultDblClick(tab, row, column, event) {
      let $this = this;
      let rowRef = this.getTabRef(tab, "Ref_" + row.ID);
      if (!rowRef) return;
      const expandIcon = rowRef.parentNode.parentNode.parentNode.querySelector(
        ".el-table__expand-icon"
      );
      if (expandIcon) expandIcon.click();
    },
    //获取参照编码字段
    getRefCodeField(refData) {
      if (!refData || !refData.RefFields || refData.RefFields.length === 0)
        return NaN;
      return refData.RefFields.find((refField) => refField.IsEdit);
    },
    //获取参照编码字段
    getRefNameField(refData) {
      if (!refData || !refData.RefFields || refData.RefFields.length === 0)
        return NaN;
      return refData.RefFields.find((refField) => refField.IsName);
    },
    //获取参照OQL
    getRefOQL(refData) {
      if (!refData) return "";
      let oqls = [];
      oqls.push("select ");
      oqls.push(this.getRefSelectOQL(refData));
      oqls.push("\r\n");
      oqls.push("from ");
      oqls.push(this.getEntityOQLFullName(refData.RefEntityName));
      if (refData.Filter && refData.Filter.length > 0) {
        oqls.push("\r\n");
        oqls.push("where ");
        oqls.push(refData.Filter);
      }
      if (refData.RefOrderFields && refData.RefOrderFields.length > 0) {
        oqls.push("\r\n");
        oqls.push("order by ");
        oqls.push(this.getRefOrderOQL(refData));
      }
      return oqls.join("");
    },
    //获取参照字段OQL
    getRefSelectOQL(refData) {
      let oqls = [];
      if (refData.RefFields && refData.RefFields.length > 0) {
        let isFirst = true;
        refData.RefFields.forEach((refField, index) => {
          if (!refField.IsVisible) return;
          if (!isFirst) oqls.push(",");
          isFirst = false;
          oqls.push(
            refField.RefAttributeName.split(":")[1] +
              " as " +
              refField.DisplayName
          );
        });
      } else {
        oqls.push("*");
      }
      return oqls.join("");
    },
    //获取参照排序OQL
    getRefOrderOQL(refData) {
      let oqls = [];
      if (refData.RefOrderFields && refData.RefOrderFields.length > 0) {
        let isFirst = true;
        refData.RefOrderFields.forEach((refOrderField, index) => {
          if (!isFirst) oqls.push(",");
          isFirst = false;
          oqls.push(
            refOrderField.RefAttributeName.split(":")[1] +
              (refOrderField.Direction &&
              refOrderField.Direction.toLowerCase() === "desc"
                ? " desc"
                : "")
          );
        });
      }
      return oqls.join("");
    },
    //全部展开/全部收缩
    expandRefQueryTab(tab, expanded) {
      let tableRef = this.getTabRef(tab, "refQueryResultTable");
      if (!tableRef) return;
      const list = tableRef.$el.querySelectorAll(".el-table__expand-icon");
      if (list && list.length > 0) {
        list.forEach((rowRef, index) => {
          if (
            expanded &&
            !rowRef.className.includes("el-table__expand-icon--expanded")
          )
            rowRef.click();
          if (
            !expanded &&
            rowRef.className.includes("el-table__expand-icon--expanded")
          )
            rowRef.click();
        });
      }
    },
    //按显示名称排序
    sortRefDisplayName(a, b) {
      return this.sortStringMethod(a.DisplayName, b.DisplayName);
    },
    //按参照是否有参数排序
    sortRefParams(a, b) {
      let aP = a.RefParams && a.RefParams.length > 0;
      let bP = b.RefParams && b.RefParams.length > 0;
      return aP - bP;
    },
    //字段过滤
    filterRefPropertyHandler(value, row, column) {
      const property = column["property"];
      return row[property] === value;
    },
    //字段过滤
    filterRefParamsHandler(value, row, column) {
      let exist = row.RefParams && row.RefParams.length > 0 ? true : false;
      return exist === value;
    },
    //清除过滤
    clearRefQueryFilter(tab) {
      let tableRef = this.getTabRef(tab, "refQueryResultTable");
      if (!tableRef) return;
      tableRef.clearFilter();
    },
    //#endregion
    //#region FormQuery
    //新增FormQueryTab
    addFormQueryTab(srcTab, queryString, likeChecked) {
      let tabType = "formQuery";
      let keyID = srcTab
        ? tabType + "-" + srcTab.name
        : tabType + "-" + Math.uuid();
      if (this.currentTabIndex === keyID) return;
      let tab = this.tabs.find((item) => item.name && item.name == keyID);
      if (tab) {
        tab.preTabIndex = this.currentTabIndex;
        this.currentTabIndex = tab.name;
        return;
      }
      let $this = this;
      tab = {
        name: keyID,
        type: tabType,
        title: "Form查询",
        srcTab: srcTab,
        preTabIndex: $this.currentTabIndex,
        queryForm: {
          queryString: queryString,
          likeChecked: typeof likeChecked !== "undefined" ? likeChecked : true,
          loading: false,
        },
        queryResult: [],
      };
      $this.tabs.push(tab);
      $this.currentTabIndex = keyID;
      if (queryString) {
        $this.$nextTick(() => {
          $this.queryForm(tab);
        });
      }
    },
    //查询Form
    queryForm(tab) {
      let parameter = {
        queryString: tab.queryForm.queryString,
        like: tab.queryForm.likeChecked,
      };
      tab.queryForm.loading = true;
      let $this = this;
      this.api().queryForm(parameter, function (res) {
        console.log("查询结果", res);
        tab.queryForm.loading = false;
        if (res.code === 0) {
          tab.queryResult = res.data.map((item, index) => {
            item.activeNames = [];
            return item;
          });
        } else {
          $this.$notify.error({
            title: "错误",
            message: res && res.msg ? res.msg : "未知",
            duration: 2000,
          });
        }
      });
    },
    //查询结果行双击事件
    onFormQueryResultDblClick(tab, row, column, event) {
      let $this = this;
      let rowRef = this.getTabRef(tab, "Form_" + row.ID);
      if (!rowRef) return;
      const expandIcon = rowRef.parentNode.parentNode.parentNode.querySelector(
        ".el-table__expand-icon"
      );
      if (expandIcon) expandIcon.click();
    },
    //全部展开/全部收缩
    expandFormQueryTab(tab, expanded) {
      let tableRef = this.getTabRef(tab, "formQueryResultTable");
      if (!tableRef) return;
      const list = tableRef.$el.querySelectorAll(".el-table__expand-icon");
      if (list && list.length > 0) {
        list.forEach((rowRef, index) => {
          if (
            expanded &&
            !rowRef.className.includes("el-table__expand-icon--expanded")
          )
            rowRef.click();
          if (
            !expanded &&
            rowRef.className.includes("el-table__expand-icon--expanded")
          )
            rowRef.click();
        });
      }
    },
    //按显示名称排序
    sortFormDisplayName(a, b) {
      return this.sortStringMethod(a.DisplayName, b.DisplayName);
    },
    //按URI排序
    sortFormURIName(a, b) {
      let aURI = a.AssemblePage ? a.AssemblePage.URI : "";
      let bURI = b.AssemblePage ? b.AssemblePage.URI : "";
      return this.sortStringMethod(aURI, bURI);
    },
    //排序装配页面排序
    sortFormAssemblePage(a, b) {
      let aP = a.AssemblePage && a.AssemblePage.ID > 0;
      let bP = b.AssemblePage && b.AssemblePage.ID > 0;
      return aP - bP;
    },
    //排序装配菜单排序
    sortFormAssembleMenu(a, b) {
      let aP = a.AssembleMenu && a.AssembleMenu.ID > 0;
      let bP = b.AssembleMenu && b.AssembleMenu.ID > 0;
      return aP - bP;
    },
    //字段过滤
    filterFormPropertyHandler(value, row, column) {
      const property = column["property"];
      return row[property] === value;
    },
    //页面过滤
    filterFormAssemblePageHandler(value, row, column) {
      let exist = row.AssemblePage && row.AssemblePage.ID > 0 ? true : false;
      return exist === value;
    },
    //菜单字段过滤
    filterFormAssembleMenuHandler(value, row, column) {
      let exist = row.AssembleMenu && row.AssembleMenu.ID > 0 ? true : false;
      return exist === value;
    },
    //清除过滤
    clearFormQueryFilter(tab) {
      let tableRef = this.getTabRef(tab, "formQueryResultTable");
      if (!tableRef) return;
      tableRef.clearFilter();
    },
    //#endregion
    //#region 其它
    //handle快捷键事件
    handleKeyEvent(e) {
      var $this = this;
      //console.log("handleKeyEvent:", e);
      if (!this.currentTabIndex) return;
      let tab = this.tabs.find((item) => item.name == this.currentTabIndex);
      if (!tab) return;
      if (tab.type === "bpsv") {
        //F9
        if (e.keyCode === 120) {
          this.totalLoadProxyData(tab);
        }
        //F10
        if (e.keyCode === 121) {
          this.sendProxyReqeust(tab);
        }
      }
      if (tab.type === "oql") {
        //F9
        if (e.keyCode === 120) {
          this.getSQLByOQL(tab);
        }
        //F10
        if (e.keyCode === 121) {
          this.getOQLQueryResult(tab);
        }
      }
    },
    //类型格式化
    classTypeFormatter(row, column, cellValue, index) {
      return this.getEnumOptionName(this.enums.classTypeOptions, cellValue);
    },
    //获取项名称
    getEnumOptionName(options, optionValue) {
      let option = options.find((item) => item.value == optionValue);
      if (option) return option.name;
      return "";
    },
    //获取是否选择项
    getYesNoOptions() {
      return [
        { text: "是", value: true },
        { text: "否", value: false },
      ];
    },
    //获取实体OQL全称
    getEntityOQLFullName(fullName) {
      if (!fullName) return "";
      return fullName.replace(/\./g, "::");
    },
    //联合数组
    joinArrayString(arr) {
      if (!arr) return "";
      return arr.join(",");
    },
    //清除特殊字符
    removeSpecialChar(str) {
      if (!str) return str;
      return str.replace(
        /[`~!#$%^\-&*)=|{}':;',.\\\[\]<>\/?～！＠＃￥％……＆×（）——＋｀－＝［］＼；＇，．／｛｝｜：“《》？\s]/g,
        ""
      );
    },
    //字符串排序
    sortStringMethod(str1, str2) {
      let res = 0;
      for (let i = 0; ; i++) {
        if (!str1[i] || !str2[i]) {
          res = str1.length - str2.length;
          break;
        }
        const char1 = str1[i];
        const char1Type = this.getChartType(char1);
        const char2 = str2[i];
        const char2Type = this.getChartType(char2);
        // 类型相同的逐个比较字符
        if (char1Type[0] === char2Type[0]) {
          if (char1 === char2) {
            continue;
          } else {
            if (char1Type[0] === "zh") {
              res = char1.localeCompare(char2);
            } else if (char1Type[0] === "en") {
              res = char1.charCodeAt(0) - char2.charCodeAt(0);
            } else {
              res = char1 - char2;
            }
            break;
          }
        } else {
          // 类型不同的，直接用返回的数字相减
          res = char1Type[1] - char2Type[1];
          break;
        }
      }
      return res;
    },
    getChartType(char) {
      // 数字可按照排序的要求进行自定义，我这边产品的要求是
      // 数字（0->9）->大写字母（A->Z）->小写字母（a->z）->中文拼音（a->z）
      if (/^[\u4e00-\u9fa5]$/.test(char)) {
        return ["zh", 300];
      }
      if (/^[a-zA-Z]$/.test(char)) {
        return ["en", 200];
      }
      if (/^[0-9]$/.test(char)) {
        return ["number", 100];
      }
      return ["others", 999];
    },
    //复制到剪贴板
    copyToClipboard(content) {
      if (window.clipboardData) {
        window.clipboardData.setData("text", content);
      } else {
        (function (content) {
          document.oncopy = function (e) {
            e.clipboardData.setData("text", content);
            e.preventDefault();
            document.oncopy = null;
          };
        })(content);
        document.execCommand("Copy");
      }
      this.$message({
        message: "复制成功",
        type: "success",
        duration: 1000,
      });
    },
    //关闭Tab的弹窗
    closeTabPopover(tab, popoverName) {
      let popovers = this.$refs[tab.name + popoverName];
      if (!popovers || !popovers.length || popovers.length === 0) return;
      let popover = popovers[0];
      popover.doClose();
    },
    //#endregion
  },
  watch: {},
  computed: {
    urlObj: function () {
      var url = window.location.href;
      if (url) {
        var _url = url.split("?")[1];
        if (!_url) {
          return {};
        }
        var windowHref = _url.split("&");
        var obj = {};
        for (var i = 0; i < windowHref.length; i++) {
          var arr = windowHref[i].split("=");
          obj[arr[0]] = arr[1];
        }
        return obj;
      }
    },
  },
  beforeDestroy() {
    document.removeEventListener("keydown", this.handleKeyEvent);
  },
});
